This week, I ran into a stupid problem. It took me a while to find the cause of this problem.
I'm illustrating the problem based on a simple example. Imagine you have a java.util.Set and you want to remove items from it while iterating it.
So I'm having a Set of Strings with different kind of car types. I want to remove the type: "Renault".
So I was trying something like this:
import java.util.HashSet; import java.util.Set; public class MyCustomSetIterator { public static void main(String[] args) { // init Set Set<String> set = new HashSet<String>(); set.add("BMW"); set.add("Mercedes"); set.add("Renault"); set.add("Audi"); // loop Set (using enhanced for loop) for (String s : set) { if (s.equals("Renault")) { set.remove(s); } } } }
This code compiles, but when you run it, you will get following exception:
Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793) at java.util.HashMap$KeyIterator.next(HashMap.java:828) at MyCustomSetIterator.main(MyCustomSetIterator.java:18)
The enhanced for loop is creating an Iterator (in the background). If you remove items from the Set, the Iterator will be broken as you're deleting "nodes" on which the Iterator wants to loop.
To remove it properly, you have to remove the item by using the Iterator
import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class MyCustomSetIterator { public static void main(String[] args) { // init Set Set<String> set = new HashSet<String>(); set.add("BMW"); set.add("Mercedes"); set.add("Renault"); set.add("Audi"); // loop Set (using iterator) Iterator<String> it = set.iterator(); while (it.hasNext()) { String s = it.next(); if (s.equals("Renault")) { it.remove(); } } } }
The remove() method deletes the item, but it will not brake the internal structure of the set :-) ...
Add new comment