Reputation: 971
I have a TreeSet that contains integers. I loop through this set and "consume" the integers one by one. During each loop I need to increase the remaining, uncomsumed integers with 1.
For example, I start with a set with four values: 2, 3, 5, 8
. After the first loop where I consume 2
the result should be a set with this content 4, 6 , 9
. After the second loop, where 4
is consumed, it should be 7, 10
and so on.
2, 3, 7, 10
or 2, 4, 7, 10
or just 7, 10
. (The set is gonna be discarded after this loop)This is my code
for (Integer i : positionSet) {
TreeSet <Integer> tmpSet = new TreeSet<>();
//use i for something
//positionSet.remove(i); //I tried with this both on and off, but it made no difference
for (Integer j : positionSet) {
tmpSet.add(j + 1);
}
positionSet.clear();
positionSet.addAll(tmpSet);
}
It crashes on the second round with a java.util.ConcurrentModificationException
, which I presume is caused by me modifying the set that is used in the loop-header.
How do I modify the contents of the set while looping over it? I tried copying the set back and forth in a couple of different ways but the code constantly fails with the same error message. I must not modify the set while looping, however modifying the set is the whole purpose of this loop.//
Upvotes: 2
Views: 259
Reputation: 9541
You cannot modify a data structure during iteration, except for the allowed provisions. For an iterator this is only Iterator.remove()
, but a for-each doesn't have such provision, nor can you affect other elements.
The best you can do is create a while loop that's independent of the data structure:
while (!positionSet.isEmpty()) {
Integer i = <take one element out of positionSet somehow>;
//positionSet.remove(i); //remove if the previous line didn't already remove it
//use i for something
TreeSet <Integer> tmpSet = new TreeSet<>();
for (Integer j : positionSet) {
tmpSet.add(j + 1);
}
positionSet.clear();
positionSet.addAll(tmpSet);
}
Upvotes: 2