• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

for loop question

 
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 959
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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().
 
Bartender
Posts: 4116
72
Mac TypeScript Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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 ?
 
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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:
 
Bartender
Posts: 2911
150
Google Web Toolkit Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
isnt there a clear method ??
 
salvin francis
Bartender
Posts: 2911
150
Google Web Toolkit Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I meant

 
Rob Spoor
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes there is. Both Freddy and I were merely pointing out the removal technique in general.
 
Warren Bell
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Rob Spoor
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Bartender
Posts: 2911
150
Google Web Toolkit Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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)

 
a fool thinks himself to be wise, but a wise man knows himself to be a fool - shakespeare. foolish tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic