Not allowed to manipulate TreeSet in for-loop

Viewed 103

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.

  • I don't need the last value to be increased a step after it has been consumed (but it is ok if it is).
  • It is ok if the consumed values remain in the set, and it doesn't matter if they are at their original or increased value. In other words, after the second loop, it would be ok if the set contained 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.//

1 Answers

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);
}
Related