Huyết Công Tử
Huyết Công Tử

Reputation: 175

All element of List is the same after adding in java

I recently got a mistake in my java project because of my misunderstanding. I have the following code:

 Post post = new Post(); // Post is my custom class
 List<Post> list = new ArrayList<Post>();
 for( int i = 0; i < num; i++){
      post.setTitle( TITLE[i] ); //TITLE[] is a array of String.
      list.add(post);
 }

And after that all of element in the List list is the same and equal to the post with the title TITLE[num-1]. I know I got a misunderstanding in this problem because when I put the contructor

 Post post = new Post();

inside the loop for, every thing is Ok. But anybody can explain this for me, please? Thank you very much.

Upvotes: 4

Views: 3645

Answers (4)

Kevin Workman
Kevin Workman

Reputation: 42174

What you have is a single Post. Inside your loop, you're setting the name of that same Post over and over again, then adding it to a List. Each element of the List points to the same instance of Post, which you've renamed a bunch of times.

Putting the Post post = new Post() line inside the loop creates a new instance of Post, assigns it a name, and adds that new instance to the List. Now each index of the List points to a different instance of Post, each with a different name.

Think about it this way: pretend you have a dog named Bingo. You take a picture of the dog, then add that picture to a photo album. You then rename that dog to Fido. You take another picture of that same dog, then add that picture to the photo album. Repeat this process 100 times. Do you have 100 pictures of different dogs with different names? Or do you have 100 pictures of the same dog with whatever name you gave it last?

Recommended reading: http://www.javaranch.com/campfire/StoryCups.jsp And its follow-up: http://www.javaranch.com/campfire/StoryPassBy.jsp

Upvotes: 2

Thom
Thom

Reputation: 15092

Think of a class as a cookie cutter and memory as dough. Every time you call a constructor, you stamp out some of the memory into a shape. This is an object instance.

If you only call the constructor once, you only have one instance of the object. Every time through the loop, you place a pointer to that instance in the collection. At the end of the loop, you have all of these pointers to the same object instance.

When you move the constructor into the loop, every time through the loop, you create a new object instance. You store a pointer to that instance in the list. Now, at the end of the loop, you have one object instance for every pointer in your list.

Upvotes: 0

robertoia
robertoia

Reputation: 2361

post is an instance of the object Post.

What you are doing in post.setTitle(...) is modifying post and storing a reference to it in the list. All the elements in the list are references to the same Post object, so if you modify it, all the elements in the list will change.

If you want to store diferent Post items, you need to create different Post items each time.

Upvotes: 2

Christian Tapia
Christian Tapia

Reputation: 34166

You have just created one Post object, so in the lines

post.setTitle( TITLE[i] ); //TITLE[] is a array of String.
list.add(post);

you are just changing the title of that Post and adding it to the list. At the end, you will have only one Post in the list, but multiple times.

Why? Because in fact, objects are references to locations in memory, so you are adding the same reference (same location) on each iteration.

How can you solve it? You can create a new object on each iteration:

for( int i = 0; i < num; i++){
    Post post = new Post();
    post.setTitle( TITLE[i] );
    list.add(post);
}

Upvotes: 6

Related Questions