By Duncan Jones


2013-11-07 18:11:59 8 Comments

I'm adding three different objects to an ArrayList, but the list contains three copies of the last object I added.

For example:

for (Foo f : list) {
  System.out.println(f.getValue());
}    

Expected:

0
1
2

Actual:

2
2
2

What mistake have I made?

Note: this is designed to be a canonical Q&A for the numerous similar issues that arise on this site.

4 comments

@Duncan Jones 2013-11-07 18:11:59

This problem has two typical causes:

  • Static fields used by the objects you stored in the list

  • Accidentally adding the same object to the list

Static Fields

If the objects in your list store data in static fields, each object in your list will appear to be the same because they hold the same values. Consider the class below:

public class Foo {
  private static int value; 
  //      ^^^^^^------------ - Here's the problem!

  public Foo(int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }
}

In that example, there is only one int value which is shared between all instances of Foo because it is declared static. (See "Understanding Class Members" tutorial.)

If you add multiple Foo objects to a list using the code below, each instance will return 3 from a call to getValue():

for (int i = 0; i < 4; i++) {      
  list.add(new Foo(i));
}

The solution is simple - don't use the static keywords for fields in your class unless you actually want the values shared between every instance of that class.

Adding the Same Object

If you add a temporary variable to a list, you must create a new instance of the object you are adding, each time you loop. Consider the following erroneous code snippet:

List<Foo> list = new ArrayList<Foo>();    
Foo tmp = new Foo();

for (int i = 0; i < 3; i++) {
  tmp.setValue(i);
  list.add(tmp);
}

Here, the tmp object was constructed outside the loop. As a result, the same object instance is being added to the list three times. The instance will hold the value 2, because that was the value passed during the last call to setValue().

To fix this, just move the object construction inside the loop:

List<Foo> list = new ArrayList<Foo>();        

for (int i = 0; i < 3; i++) {
  Foo tmp = new Foo(); // <-- fresh instance!
  tmp.setValue(i);
  list.add(tmp);
}

@Dev 2014-12-10 09:20:27

hello @Duncan nice solution, i want to ask you that in "Adding the Same Object" why three different instance will hold the value 2 ,aren't all three instance should hold 3 different values? hope you will reply soon, thanks

@Duncan Jones 2014-12-10 09:22:56

@Dev Because the same object (tmp) is added to the list three times. And that object has a value of two, because of the call to tmp.setValue(2) in the final iteration of the loop.

@Dev 2014-12-10 09:33:24

ok so here problem is because of same object , Is it so if i add same object three times in a array list ,all three location of arraylist obj will refer to same object?

@Duncan Jones 2014-12-10 09:34:15

@Dev Yup, that's exactly it.

@a.t. 2019-05-28 09:51:07

An obvious fact I initially overlooked: concerning the part you must create a new instance each time you loop in the section Adding the same object: Please note the instance referred to concerns the object you are adding, NOT the object you are adding it to.

@basti12354 2017-10-24 20:45:23

Had the same trouble with the calendar instance.

Wrong code:

Calendar myCalendar = Calendar.getInstance();

for (int days = 0; days < daysPerWeek; days++) {
    myCalendar.add(Calendar.DAY_OF_YEAR, 1);

    // In the next line lies the error
    Calendar newCal = myCalendar;
    calendarList.add(newCal);
}

You have to create a NEW object of the calendar, which can be done with calendar.clone();

Calendar myCalendar = Calendar.getInstance();

for (int days = 0; days < daysPerWeek; days++) {
    myCalendar.add(Calendar.DAY_OF_YEAR, 1);

    // RIGHT WAY
    Calendar newCal = (Calendar) myCalendar.clone();
    calendarList.add(newCal);

}

@Faraz Durrani 2017-02-27 06:21:43

Every time you add an object to an ArrayList, make sure you add a new object and not already used object. What is happening is that when you add the same 1 copy of object, that same object is added to different positions in an ArrayList. And when you make change to one, because the same copy is added over and over again, all the copies get affected. For example, Say you have an ArrayList like this:

ArrayList<Card> list = new ArrayList<Card>();
Card c = new Card();

Now if you add this Card c to list, it will be added no problem. It will be saved at location 0. But, when you save the same Card c in the list, it will be saved at location 1. So remember that you added same 1 object to two different locations in a list. Now if you make a change that Card object c, the objects in a list at location 0 and 1 will also reflect that change, because they are the same object.

One solution would be to make a constructor in Card class, that accepts another Card object. Then in that constructor, you can set the properties like this:

public Card(Card c){
this.property1 = c.getProperty1();
this.property2 = c.getProperty2(); 
... //add all the properties that you have in this class Card this way
}

And lets say you have the same 1 copy of Card, so at the time of adding a new object, you can do this:

list.add(new Card(nameOfTheCardObjectThatYouWantADifferentCopyOf));

@Shashank 2016-07-13 12:31:58

Your problem is with the type static which requires a new initialization every time a loop is iterated. If you are in a loop it is better to keep the concrete initialization inside the loop.

List<Object> objects = new ArrayList<>(); 

for (int i = 0; i < length_you_want; i++) {
    SomeStaticClass myStaticObject = new SomeStaticClass();
    myStaticObject.tag = i;
    // Do stuff with myStaticObject
    objects.add(myStaticClass);
}

Instead of:

List<Object> objects = new ArrayList<>(); 

SomeStaticClass myStaticObject = new SomeStaticClass();
for (int i = 0; i < length; i++) {
    myStaticObject.tag = i;
    // Do stuff with myStaticObject
    objects.add(myStaticClass);
    // This will duplicate the last item "length" times
}

Here tag is a variable in SomeStaticClass to check the validity of the above snippet; you can have some other implementation based on your use case.

@4castle 2017-02-03 03:55:17

What do you mean by "type static"? What would be a non-static class to you?

@Shashank 2017-02-04 11:37:52

e.g. non-static: public class SomeClass{/*some code*/} & static: public static class SomeStaticClass{/*some code*/}. I hope it is clearer now.

@Shashank 2017-02-04 11:46:29

Since, all objects of a static class share same address, if they are initialized in a loop and are set with different values in each iteration. All of them will end up having identical value which will equal to the value of the last iteration or when the last object was modified. I hope it is clearer now.

Related Questions

Sponsored Content

11 Answered Questions

[SOLVED] Getting the last element of a list

  • 2009-05-30 19:28:53
  • Janusz
  • 1660563 View
  • 1712 Score
  • 11 Answer
  • Tags:   python list indexing

16 Answered Questions

[SOLVED] How to get the last value of an ArrayList

  • 2009-03-26 22:38:57
  • Jessy
  • 608703 View
  • 518 Score
  • 16 Answer
  • Tags:   java arraylist

12 Answered Questions

[SOLVED] How to randomly select an item from a list?

  • 2008-11-20 18:42:21
  • Ray Vega
  • 1247898 View
  • 1570 Score
  • 12 Answer
  • Tags:   python list random

15 Answered Questions

[SOLVED] How to clone or copy a list?

28 Answered Questions

[SOLVED] Finding the index of an item given a list containing it in Python

  • 2008-10-07 01:39:38
  • Eugene M
  • 3289691 View
  • 2708 Score
  • 28 Answer
  • Tags:   python list indexing

21 Answered Questions

[SOLVED] How can I count the occurrences of a list item?

  • 2010-04-08 13:30:00
  • weakish
  • 1371021 View
  • 1324 Score
  • 21 Answer
  • Tags:   python list count

25 Answered Questions

[SOLVED] Why not inherit from List<T>?

9 Answered Questions

[SOLVED] Python join: why is it string.join(list) instead of list.join(string)?

  • 2009-01-29 22:45:13
  • Evan Fosmark
  • 1201771 View
  • 1588 Score
  • 9 Answer
  • Tags:   python string list join

5 Answered Questions

[SOLVED] Why is [] faster than list()?

14 Answered Questions

[SOLVED] Why does this code using random strings print "hello world"?

  • 2013-03-03 04:38:06
  • 0x56794E
  • 190412 View
  • 1697 Score
  • 14 Answer
  • Tags:   java string random

Sponsored Content