tags:

views:

102

answers:

3

I have a list in a Data Object in java which houses data retrieved from a database, be it multiple or single rows. I retrieve the List from the BO and dump it into a temporary list so that I can iterate over it to extract Data. When I just check the size of the list after doing the first assignment, everything is going on fine, but when I try and iterate over the list in a for loop, its size was being reduced. I was testing with two rows of data in the list, but in the loo, its size always used to be one. And the funny part is, I have used this logic in many places many times, but in this one Business Process in which I was writing this, it behaved very erratically. Any on has any leads on this? Here is a sample code

List temp = new ArrayList();

temp = dummyBO.getList(0) // Retrieves the List at index 0 from the BO

//Imagine the list has 2 rows of data. This prints the size as 2
System.out.println("size: "+temp.size());

System.out.println("Contents: "+temp.get(0);
System.out.println("Contents: "+temp.get(1);

//This is where the List starts behaving erratically

**for(int i=0;i<temp.size();i++){
     System.out.println("size: "+temp.size()); //here the size is displayed as 1
     System.out.println("Contents: "+temp.get(i); // here only the data at index 0 is shown
}**

P.S. This java code is written in the snippet section in IBM WID 6.1

+2  A: 

I would suspect that this

temp = dummyBO.getList(0)

retrieves a reference to a list, not a copy. So whatever has provided you with this reference would be at liberty to change that list. Do you need to take a defensive copy of this list ?

Brian Agnew
Hi Brian, could you please elaborate on the defensive copy that you mentioned?
Aditya
+3  A: 

You said:

I retrieve the List from the BO and dump it into a temporary list

And your snippet says:

// original snippet
List temp = new ArrayList();    
temp = dummyBO.getList(0);

It's impossible to say this with absolute certainty, but this is a code smell, and in all likelihood, the bug that is causing your problem.

The smelly part is the fact that you created a new ArrayList, but it becomes garbage immediately. This snippet DOES NOT populate that ArrayList with the elements from the dummyBO list. It sets temp to refer to a newly created object, but then it lets go of that object to refer to something else entirely. Remember that = for objects is simply a reference assignment in Java; it can NOT be overloaded to do anything different.

Perhaps you want something like this instead:

// possible fix #1
List temp = new ArrayList(dummyBO.getList(0));

This will in fact create a new ArrayList, and populates that list with the elements of the list you get from dummyBO. This uses the ArrayList(Collection) constructor, which iterates over the Collection and adds its elements to the list.

Alternatively you could also do something like this:

// possible fix #2
List temp = new ArrayList();
temp.addAll(dummyBO.getList(0));
polygenelubricants
Hi, thanks a lot for your suggestions. It makes a lot of sense. Will try out this and get back on what worked. :)
Aditya
A: 

As the other answers say, you need to copy the contents of the list.

But your problems are deeper than that. It is clear that another thread is changing the contents of the list. Simply copying the list that getList(0) has returned is not going to be reliable. The other thread might change the list while you are copying it!

Instead, you need to change the getList(int) method so that it creates the copy of the list, and it does it holding a lock to stop the list being changed while it is being copied.

EDIT

The list copy can be made using the copy constructor; e.g. use new ArrayList(someList) as per @polygenelubricants' answer.

But there is no simple answer to how you lock the list to stop the list being changed while it being copied. It depends on what else is accessing and updating the list ... and how.

Stephen C
Hi stephen, can you please tell me, how to achieve the creation of copy and locking of the list? Thanks a lot for your wonderful suggestion :)
Aditya