You need to either
- use a Set which doesn't trigger a ConcurrentModifcationException e.g. ConcurrentXxxSet
- take a copy of the set before altering it.
The simplest change is
for (Object o: set.toArray()) {
if (condition(o))
set.add(something);
}
With generics a simpler solution might be
Set<T> set =
for(T t: new HashSet<T>(set)) {
// something which might add to set
}
Note: this will prevent it iterating over elements you just added.
Note2: using the concurrent sets may result in you seeing added elements or possibly not.
If you really need to see elements as you add them you need to use a list, possibly instead, or as well.
List<T> list = new ArrayList<>(set);
for(int i = 0; i < list.size(); i++) {
T t = list.get(i);
if (condition)
// if it is not a duplicate
if (set.add(something))
list.add(something);
}
This will allow you to see elements you have added in the loop in a reliable manner. Note: some care needs to be take to not create an infinite loop and run out of memory.
An alternative is to use a queue instead of a list. This might be nicer, but I suspect less efficient.
Queue<T> q = new ConcurrentLinkedQueue<>(set);
for(T t : q) {
if (condition)
// if it is not a duplicate
if (set.add(something))
q.add(something);
}