-1

I am trying to add objects of a class to a vector. But on adding the second object the first objects gets replaced with the second object.

Here is my code:

    Vector res = new Vector();
    Item item = new Item();
    item.Name = "maclean";
    item.Des = "abcd";
    item.Price = "RS 350";
    item.image = "c.gif";
    res.add(item);
    item.Name = "pinto";
    item.Des = "gief";
    item.Price = "RS 450";
    item.image = "d.gif";
    res.add(item);
    for (int i = 0; i < res.size(); i++) {
        item = (Item) res.get(i);
        System.out.println(item.Name);
    }

Here is my implementation of the Item class used above.

public class Item {

    public String Name=null;
    public String Price=null;
    public String Des=null;
    public String image=null;
}

Output that I am getting:

pinto
pinto

Desired Output:

maclean 
pinto

The above is a simple version of what I am trying to do.


Hi had forgot to mention earlier. I cannot create a new instance every time. Can any one suggest a suggestion so that i do not need to create a new instance every time. I want to know whether there is some structure other than vector which could store the entire object instead of pointer to the object.

Is there any structure readily available which i could use for my requirement. Or should a create a new array of the class objects.

Derek W
  • 9,708
  • 5
  • 58
  • 67
Maclean Pinto
  • 1,075
  • 2
  • 17
  • 39

5 Answers5

2

You're not creating a new instance of Item. You're just changing the values of your original instance of Item.

So what you end up with in your instance of Vector are two references to the same Item object.

Try modifying your code to this:

Vector res = new Vector();
Item item = new Item();
item.Name = "maclean";
item.Des = "abcd";
item.Price = "RS 350";
item.image = "c.gif";
res.add(item);
Item item2 = new Item();
item2.Name = "pinto";
item2.Des = "gief";
item2.Price = "RS 450";
item2.image = "d.gif";
res.add(item2);
for (int i = 0; i < res.size(); i++) {
    item = (Item) res.get(i);
    System.out.println(item.Name);
}

When you use the new keyword in Java you're reserving space on the heap for your object. Here you are not using new to create a new object of type Item. So you're still referencing the same instance of Item on the heap, hence why that object is being modified. For more information about creating objects in Java see here.

Per your edit:

Hi had forgot to mention earlier. I cannot create a new instance every time.

There is a way to "work around" this, by creating a collection that internally makes copies of the objects you add to it.

So here is a special collection called CopyCollection that I just wrote:

public class CopyCollection {

    private List<Item> list = new ArrayList();

    public void add(Item item)
    {
        Item newItem = new Item();
        newItem.Name = item.Name;
        newItem.Price = item.Price;
        newItem.Des = item.Des;
        newItem.image = item.image;

        list.add(newItem);
    }

    public Item get(int index)
    {
        return list.get(index);
    }

    public int size()
    {
        return list.size();
    }   
}

And you would use it like this:

public static void main(String[] args) {
    CopyCollection res = new CopyCollection();
    Item item = new Item();
    item.Name = "maclean";
    item.Des = "abcd";
    item.Price = "RS 350";
    item.image = "c.gif";
    res.add(item);
    item.Name = "pinto";
    item.Des = "gief";
    item.Price = "RS 450";
    item.image = "d.gif";
    res.add(item);
    for (int i = 0; i < res.size(); i++) {
        item = res.get(i);
        System.out.println(item.Name);
    }
}

So under the hood, CopyCollection makes use of an ArrayList containing objects of type Item - this also removes the need for casting later. Whenever you add another configuration of your single Item object to this collection, the add method for this collection creates a new instance of Item with the current configuration of the Item object that was passed to it.

Derek W
  • 9,708
  • 5
  • 58
  • 67
2

Create new insntance of Item each time.

    Vector res = new Vector();
    Item item = new Item();
    item.Name = "maclean";
    item.Des = "abcd";
    item.Price = "RS 350";
    item.image = "c.gif";
    res.add(item);
    Item item2 = new Item();   <---
    item2.Name = "pinto";
    item2.Des = "gief";
    item2.Price = "RS 450";
    item2.image = "d.gif";
    res.add(item2);

That resolves your problem.

Seriously Vectors are died/replaced by Collection framework.

I suggest you to use List<Item> instead of Vector

Helpful Links:


Edit :

I cannot create a new instance every time.

Not possible to having multiple copies of data with a single object. You have to create a new instance

Community
  • 1
  • 1
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • Hi i am looking for new storage class. The entire purpose of this API is not to create a new instance – Maclean Pinto Oct 19 '13 at 14:14
  • @MacleanPinto You mean To clone the current object to another Object and modify that ? Do you want that ? – Suresh Atta Oct 19 '13 at 14:16
  • every time i will add the data to same object. and then add this to a storage vector. Now instead of pointer to the vector i want to store the clone of the object. so that when i change or modify the existing object the clone should remain as it is.. – Maclean Pinto Oct 19 '13 at 14:24
  • Then just before adding, clone the object and add the cloned object to the Vector. That's it. Not the original object. – Suresh Atta Oct 19 '13 at 14:26
  • I have updated my answer to provide a collection that implements this required behavior. – Derek W Oct 19 '13 at 14:45
  • @DerekW Oh !! bro. He don't want to create a new instance :). Let see how Maclean reponds on this. Anyways +1 for you. – Suresh Atta Oct 19 '13 at 14:47
  • @sᴜʀᴇsʜ ᴀᴛᴛᴀ: I guess the problem as I understood it was that they wanted their collection to create the new instances for them. Because you can have multiple references to the same object, but not the other way around. – Derek W Oct 19 '13 at 15:20
1

For each new item, you need to have "new Item();". In your code you just replaced the earlier values with new ones and put 2 references to the same item in the Vector.

Also consider using ArrayList instead of Vector. Vector is a somewhat outdated class.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
1

You have to create separate instances to place into the Vector.

Item item = new Item();
item.Name = "maclean";
item.Des = "abcd";
item.Price = "RS 350";
item.image = "c.gif";
res.add(item);
Item item2 = new Item();
item2.Name = "pinto";
item2.Des = "gief";
item2.Price = "RS 450";
item2.image = "d.gif";
res.add(item2);

You could also add a type to your Vector instance to avoid the cast you're doing in your loop:

Vector<Item> res = new Vector<>();
Makoto
  • 104,088
  • 27
  • 192
  • 230
1

If you want an Item for each entry, you need to have an Item for each entry. There is no magic way around this. What you can do is create a copy as you add the Item

// code which reuses the same object each time

list.add(item.clone()); // make the item Cloneable

list.add(new Item(item)); // use a copy constructor

Item item2 = new Item();
// copy fields from item to item2
list.add(item2); // add a copy.

BTW Doesn't use Vector unless you have to, it was replaced with ArrayList in 1998.

It appears you have a bug in your code and you can't work around this fact easily. At some point fixing the bug is the right answer.

Is there any structure readily available which i could use for my requirement.

That is not how Java collections work.

Or should a create a new array of the class objects.

I don't see how this would help.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130