This question already has answers here:
Only the last Object is added to the ArrayList
(4 answers)
Add an object to an ArrayList and modify it later
(4 answers)
Closed 7 years ago.
While adding objects to list I was able to see the object is replacing all values in the list.
Please check the below image and notice the code in for loop for duplicates of object in the list.
public static void main(String args[]) {
ArrayList<Modelclass> al = new ArrayList<Modelclass>();
Modelclass obj = new Modelclass();
for (int i = 0; i < 10; i++) {
obj.setName(2 + i);
obj.setRoolno(4 + i);
System.out.println(obj);
//if (!al.equals(obj)) {
al.add(obj);
System.out.println(obj.getName() + "" + obj.getRoolno());
//}
}
}
You are always adding the same
Modelclass obj = new Modelclass();
That you created outside of the for loop. Then, inside the loop, you are modifying the values.
Since it is always a reference to the same object, you are modifying all of the items in the ArrayList.
Try this instead:
for (int i = 0; i < 10; i++) {
Modelclass obj = new Modelclass(); //This is the key to solve it.
obj.setName(2 + i);
obj.setRoolno(4 + i);
System.out.println(obj);
al.add(obj);
System.out.println(obj.getName() + "" + obj.getRoolno());
}
Your obj variable is only being instantiated once, but being added to the list multiple times. Whenever you update the members of obj, you are updating the same piece of memory and thus every list reference shows the same (last added) data.
I guess you are new in Java? Just create new instances in the loop will work.
ArrayList<ModelClass> al = new ArrayList<ModelClass>();
for(int i=0; i<10; i++){
ModelClass obj = new ModelClass();
obj.setName(2+i);
obj.setRoolno(4+i);
al.add(obj);
}
Your problem is that you're referencing the same object cause you created the object before the loop. Should be
public static void main(String args[]) {
ArrayList<Modelclass> al = new ArrayList<Modelclass>();
for (int i = 0; i < 10; i++) {
Modelclass obj = new Modelclass();
obj.setName(2 + i);
obj.setRoolno(4 + i);
System.out.println(obj);
//if (!al.equals(obj)) {
al.add(obj);
System.out.println(obj.getName() + "" + obj.getRoolno());
//}
}
}
Related
This question already has answers here:
Initializing an array in Java using the 'advanced' for each loop [duplicate]
(5 answers)
Closed 5 years ago.
I have 2 classes. The first describes an item, and the seconds is built around an array of items of the first class.
I had learned that just creating an array of objects doesn't initialize them. So I put a for-loop in the constructor of the 2nd class to initialize all items.
Yet when entering the clear() function, all elements of the list array are still null. Why is that?
class HneAnalogItem {
String description;
String unit;
float value;
HneAnalogItem(){}
}
class HneAnalogInfo
{
static final private int MAXANALOGINFOITEMS = 100;
private HneAnalogItem[] list;
HneAnalogInfo() {
list = new HneAnalogItem[MAXANALOGINFOITEMS];
for(HneAnalogItem item : list) {
item = new HneAnalogItem();
}
clear();
}
void clear() {
for(HneAnalogItem item : list) {
item.description = "";
item.unit = "";
item.value = 0;
}
}
}
for (HneAnalogItem item : list) {
item = new HneAnalogItem();
}
This enhanced for loop doesn't initialize the array elements. It is equivalent to:
for (int i = 0; i < list.length; list++) {
HneAnalogItem item = list[i];
item = new HneAnalogItem();
}
To initialize the array elements you need:
for (int i = 0; i < list.length; list++) {
list[i] = new HneAnalogItem();
}
I'm creating an ArrayList of type B:
ArrayList<B> cert= new ArrayList<B>;
B a = util.getCerts(path).iterator().next();
this.cert.add(a);
this.certNode(certs);
I'm getting a null pointer exception when I try to set the value:
void certNode(ArrayList<B> certResp)
{
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (int i = 0; i< certResp.size(); i++) {
exp.get(i).setxxx(certResp.get(i).getxxx());
exp.get(i).setxxx(certResp.get(i).getxxx().toString());
}
}
Any help would be great!
Since you just created the ArrayList instance exp, exp.get(i) doesn't exist, so you can't call exp.get(i).setxxx(...).
EDIT :
Try :
void certNode(ArrayList<B> certResp) {
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (int i = 0; i< certResp.size(); i++) {
exp.add(certResp.get(i).getxxx());
}
}
It's hard to be sure without knowing the return value of certResp.get(i).getxxx(), but if it returns RespNode, the code above would add that RespNode instance of the list.
The problem is here : exp.get(i). exp is the newly created ArayList, so it's empty, so there is a null at index i
Your list 'exp' is empty. In the for-loop you get a value of null; calling a method from null will cause the NullPointerException.
You have to put values in the list before you try to access them.
void certNode(ArrayList<B> certResp) {
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (int i = 0; i< certResp.size(); i++) {
exp.add(new RespNode()); // <-----
exp.get(i).setxxx(certResp.get(i).getxxx());
exp.get(i).setxxx(certResp.get(i).getxxx().toString());
}
}
btw you can improve syntax
void certNode(ArrayList<B> certResp) {
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (B b : certResp){
RespNode resp = new RespNode();
resp.setxxxx(b.getxxxx());
exp.add(resp);
}
}
As you are creating new empty ArrayList i.e []
exp.get(i)
gives you null
Instead you can use add method of ArrayList
void certNode(ArrayList<B> certResp) {
//Here new empty list is created i.e exp=[] //no elements inside
//Suppose your certResp=[B#12312,B#123834] i.e two B class objects
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (int i = 0; i< certResp.size(); i++) { //Size of certResp=2 as it contains 2 B objects
RespNode res=new RespNode(); //Create a RespNode class as you want to add of certResp ArrayList<RespNode>
res.setxxx(certResp.get(i)); //Take value of xxx method of certResp.get(i) i.e B object xxx method and set into res.setXXX or RespNode class
exp.add(res); //add res object into ArrayList
}
}
I am adding five objects in the list with the help of for loop. I am initializing my object outside the for loop. In the body of for loop i am changing the object setter properties and adding it in the list. The output with this is: It will add five objects but all have the same attributes even after setting the different values for the attribute.
See the following code
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class ASD {
public static void main(String args[]) {
List list = new ArrayList<A>();
System.out.println("Before Insert List is " + list);
A obj = new A();
for (int i = 0; i < 5; i++) {
obj.setA(new Random().nextInt(10));
list.add(obj);
}
System.out.println("After Insert List is " + list);
for (int i = 0; i < 5; i++) {
A prObj = (A) list.get(i);
System.out.println("Values are" + prObj.getA());
}
}
}
class A {
int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
If I initialize A's object inside the for loop then it will add five objects and also changes the attribute for the objects. Can anyone explain this behaviour
You have created just one instance and setting it several times inside the for loop.Create a new instance of A inside the for loop, not outside it
for (int i=0;i<5;i++) {
A obj = new A();
obj.setA(new Random().nextInt(10));
list.add(obj);
}
When you are doing this -
A obj = new A();
for (int i=0;i<5;i++) {
obj.setA(new Random().nextInt(10));
list.add(obj);
you are actually adding reference to the same object after changing it's attribute setA.
That way, all of the list elements have reference to the same object (with same value of a).
You need to add new objects if you want to have different values -
for (int i=0;i<5;i++) {
obj = new A(); // new object
obj.setA(new Random().nextInt(10));
list.add(obj);
I have one method that returns an object with two arraylists:
return new Object[] {work, play};
I am trying to get them back out in another method. I have tried casting to ArrayList but I get the error 'array required, but java.lang.Object found'.
ArrayList setWork = (ArrayList)obj[0];
ArrayList setPlay = (ArrayList)obj[1];
Full code for ArrayList creation:
public static Object[] getWorkandPlay(ArrayList al) {
ArrayList work = new ArrayList();
ArrayList play = new ArrayList();
for (int i=0; i<al.size(); i++){
String item = (String) al.get(i);
if (item.startsWith("w.")) {
System.out.println("w " + item);
work.add(item);
} else if (item.startsWith("p.")) {
System.out.println("p " + item);
play.add(item);
} else {
System.out.println("Entries must start with either w. or p.\n");
}
}
return new Object[] {work, play};
}
I am doing something like this based on your code and it works...
class Test{
public static Object[] getWorkandPlay(ArrayList al) {
ArrayList work = new ArrayList();
ArrayList play = new ArrayList();
for (int i=0; i<al.size(); i++){
String item = (String) al.get(i);
if (item.startsWith("w.")) {
System.out.println("w " + item);
work.add(item);
} else if (item.startsWith("p.")) {
System.out.println("p " + item);
play.add(item);
} else {
System.out.println("Entries must start with either w. or p.\n");
}
}
return new Object[] {work, play};
}
public static void main(String[] args) {
ArrayList<String> al=new ArrayList<>();
al.add("w. test");
al.add("p. test");
Object[] obj=getWorkandPlay(al);
ArrayList setWork = (ArrayList)obj[0];
ArrayList setPlay = (ArrayList)obj[1];
}
}
output
w w. test
p p. test
return new Object[] {work, play}; i think returns an array of object. Try ArrayList result = new ArrayList();
put work andd play inside result then return result. Then
In your calling code, you should set the reference type of obj as an Object array.
You probably have
Object obj = getWorkandPlay(anArrayList); in your code. Change it to Object[] obj = getWorkandPlay(anArrayList);.
You probably have a typo somewhere in your code. This compiles for me:
import java.util.*;
public class SampleClass {
public static void main(String[] args) {
// Create an ArrayList and add some sample Strings
ArrayList al = new ArrayList();
al.add("w. test");
al.add("p. test");
Object[] obj = getWorkandPlay(al);
ArrayList setWork = (ArrayList)obj[0];
ArrayList setPlay = (ArrayList)obj[1];
}
public static Object[] getWorkandPlay(ArrayList al) {
ArrayList work = new ArrayList();
ArrayList play = new ArrayList();
for (int i=0; i<al.size(); i++){
String item = (String) al.get(i);
if (item.startsWith("w.")) {
System.out.println("w " + item);
work.add(item);
} else if (item.startsWith("p.")) {
System.out.println("p " + item);
play.add(item);
} else {
System.out.println("Entries must start with either w. or p.\n");
}
}
return new Object[] {work, play};
}
}
I want to add a user defined type, like the one shown below, to an ArrayList.
import java.util.ArrayList;
class MyObj
{
int iX;
}
public class testForLoopjava
{
public static void main(String[] args)
{
MyObj ob1 = new MyObj();
ArrayList<MyObj> al = new ArrayList<MyObj>();
int a,b;
for(int i =0;i<5;i++)
{
ob1.iX = i + 5;
al.add(ob1);
}
for(int j=0;j<5;j++)
System.out.println("iX: "+al.get(j).iX);
}
}
When I try to print the above code, iX always prints 9. i.e. iX is updated by the last value in the list. What is the reason for this? Am I doing some basic mistake.?
Output:
iX: 9
iX: 9
iX: 9
iX: 9
iX: 9
You're adding the same object to the list each time. You should use a fresh instance created within the loop.
e.g.-
ArrayList<MyObj> al = new ArrayList<MyObj>();
int a,b;
for(int i =0;i<5;i++)
{
MyObj ob1 = new MyObj();
ob1.iX = i + 5;
al.add(ob1);
}
Otherwise, your list will contain a list of references to the same instance and modifying that one instance affects every entry in that list.
This sort of issue is a strong argument for using immutable objects wherever possible. If you can, a good approach is to instantiate the iX field in the constructor and make it final thus not allowing it to change post-instantiation (check out the Java final keyword).
public class MyObj {
private final int iX;
public MyObj(int i) {
iX = i; // iX is initialised here but can't be changed again
}
}
This approach can yield a safer solution (wrt. the above) with the caveat that your objects can be changed post-instantiation. It sounds like a restrictive practice, but you'll be surprised to find many of your objects can be implemented in this fashion.
That's because you're always putting the same instance (the same object) in your list.
try:
public static void main(String[] args)
{
ArrayList<MyObj> al = new ArrayList<MyObj>();
int a,b;
for(int i =0;i<5;i++)
{
MyObj ob1 = new MyObj();
ob1.iX = i + 5;
al.add(ob1);
}
for(int j=0;j<5;j++)
System.out.println("iX: "+al.get(j).iX);
}
You're adding the same object multiple times to the list. You have only one MyObj created and you only change the int value that object is holding.
thats because you are keeping just one reference to MyObj and all elements refer to it. try modifying the code as follows:
for(int i =0;i<5;i++)
{
MyObj ob1 = new MyObj();
ob1.iX = i + 5;
al.add(ob1);
}
also, remove the ob1 definition outside of the loop.
You are changing the same object every time, so the last time in your loop it ill set ob1.iX = 4+5 (=9).
You should create a new instance everytime, so put it in your loop:
for(int i =0;i<5;i++)
{
MyObj ob1 = new MyObj();
ob1.iX = i + 5;
al.add(ob1);
}
One more version using Object array:
package com.may.arrays;
import java.util.ArrayList;
public class AddObjectToArray {
public static void main(String args[]){
ArrayList<MyObject> l_list = new ArrayList<MyObject>();
MyObject l_myObj = new MyObject();
l_myObj.holder = new MyObject2[6];
for(int i=0;i<5;i++){
l_myObj.holder[i] = new MyObject2();
l_myObj.holder[i].value = i+5;
l_list.add(l_myObj);
}
for(int j=0;j<5;j++){
System.out.println("value is: "+l_list.get(j).holder[j].value);
}
}
}
class MyObject{
MyObject2[] holder;
}
class MyObject2{
int value;
}
you are adding same object to list , because of this is giving same result.
you have to create new instance every time. :)