File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes for loop question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "for loop question" Watch "for loop question" New topic
Author

for loop question

Warren Bell
Ranch Hand

Joined: Dec 20, 2000
Posts: 56
What is the correct way to remove an object from a List in a for loop? I have run into problems with the old for loop, not the while loop, doing the same thing. It would cause the loop to loop less missing the last object in the list. Worked around it, but have not tried it with Java5 and was not sure if there was a standard way of doing it. Here are some ways I am thinking of doing it:

for(Object o : listOfObjects)
{
listOfObjects.remove(o);
}

or

int i = 0;
for(Object o : listOfObjects)
{
listOfObjects.remove(i);
i++;
}

And is there some sort of default counter or do you have to do the i++ deal?

Warren Bell
Freddy Wong
Ranch Hand

Joined: Sep 11, 2006
Posts: 959

Don't do that. You can get ConcurrentModificationException if you try to remove an element from a list in an enhanced for loop. Use java.util.Iterator.remove() to safely remove the element while looping, e.g.



Fixed the typo: Sorry, it should be iter.remove() and not list.remove().


SCJP 5.0, SCWCD 1.4, SCBCD 1.3, SCDJWS 1.4
My Blog
Vijitha Kumara
Bartender

Joined: Mar 24, 2008
Posts: 3827

Warren Bell wrote: I have run into problems with the old for loop, not the while loop, doing the same thing. It would cause the loop to loop less missing the last object in the list.


Can you show us how ? What you used to iterate the collection ?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19682
    
  19

First of all, both are a ConcurrentModificationException waiting to happen. You cannot modify most collections while iterating over them, except through the iterator that is used:
ListIterator has similar methods for adding and replacing values.


Now, as for the issue at hand. Consider a list with the following contents: [0, 1, 2, 3, 4, 5]
You then iterate over it, and remove element i

When i == 0, the list will be [1, 2, 3, 4, 5]. You increase i to 1, so the next time you remove element i you will skip the 1: [1, 3, 4, 5]. i will then be 2, and you skip the 3 as well: [1, 3, 5]. i is now 3 so it cannot remove anything.

There are two ways of solving this:
1) whenever you remove something, do not increase i:
If you use a traditional for-loop, you must decrease the counter because it always gets increased:

2) Loop backwards. This will prevent you skipping past elements:


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
salvin francis
Ranch Hand

Joined: Jan 12, 2009
Posts: 928

isnt there a clear method ??


My Website: [Salvin.in] Cool your mind:[Salvin.in/painting] My Sally:[Salvin.in/sally]
salvin francis
Ranch Hand

Joined: Jan 12, 2009
Posts: 928

I meant

Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19682
    
  19

Yes there is. Both Freddy and I were merely pointing out the removal technique in general.
Warren Bell
Ranch Hand

Joined: Dec 20, 2000
Posts: 56
OK, I am confused. I thought the newer version of the for loop can work off a Collection as long as the Collection implements Iterable which I thought all Collections do now after Java 5. I took this quote off a site, but have read this same thing elsewhere.

http://www.clanproductions.com/java5.html

On the up side, the new form can be applied to both arrays and collections seamlessly. In the expression for(<variable definition> : <expression>), the expression part can either be an instance of an array or an object that implements the Iterable interface. In Java 5 onwards, all java.util collection classes implement this interface, and so the 'new' form of the for loop can be used instead of an Iterator to iterate through any collection. This also gives developers a hook by making their classes Iterable, they can make them available for use within new forms of the for loop.

Here's an example using the java.util.LinkedHashSet.

Collection<Integer> scores = new LinkedHashSet<Integer>();
scores.add(99); // Use of auto boxing
scores.add(88);
scores.add(77);
for(Integer score : scores) {
System.out.println("This score is " + score);
}


Dosen't the loop get an Iterator to work from and therefore it is safe to remove an object from the Collection?
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
When using the enhanced for loop on an Iterable object, behind "under the covers" an iterator is used, however your program doesn't have access to it. The enhanced for loop has very specific use-cases, as you have been shown, the case where you need direct access to the Iterator is not one of them.


Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19682
    
  19

The for-each loop is only meant when you only want to access each element, not when you need to modify the collection (or iterable) itself.
salvin francis
Ranch Hand

Joined: Jan 12, 2009
Posts: 928

Its similar to what we indians call
Taking an axe and chopping off the branch you are sitting upon.

you know the end result dont you ?

Another example, writing (rather deleting a line of) the same file that you are currenty reading (i wonder if thats permissible)

 
Don't get me started about those stupid light bulbs.
 
subject: for loop question