I want to be able to remove multiple elements from a set while I am iterating over it. Initially I hoped that iterators were smart enough for the naive solution below to work.
Set<SomeClass> set = new HashSet<SomeClass>();
fillSet(set);
Iterator<SomeClass> it = set.iterator();
while (it.hasNext()) {
set.removeAll(setOfElementsToRemove(it.next()));
}
But this throws a ConcurrentModificationException
.
Note that iterator.remove() will not work as far as I can see because I need to remove multiple things at a time. Also assume that it is not possible to identify which elements to remove "on the fly", but it is possible to write the method setOfElementsToRemove()
. In my specific case it would take up a lot of memory and processing time to determine what to remove while iterating. Making copies is also not possible because of memory constraints.
setOfElementsToRemove()
will generate some set of SomeClass instances that I want to remove, and fillSet(set)
will fill the set with entries.
After searching Stack Overflow I could not find a good solution to this problem but a few hours break later I realized the following would do the job.
Set<SomeClass> set = new HashSet<SomeClass>();
Set<SomeClass> outputSet = new HashSet<SomeClass>();
fillSet(set);
while (!set.isEmpty()) {
Iterator<SomeClass> it = set.iterator();
SomeClass instance = it.next();
outputSet.add(instance);
set.removeAll(setOfElementsToRemoveIncludingThePassedValue(instance));
}
setOfElementsToRemoveIncludingThePassedValue()
will generate a set of elements to remove that includes the value passed to it. We need to remove the passed value so set
will empty.
My question is whether anyone has a better way of doing this or whether there are collection operations that support these kind of removals.
Also, I thought I would post my solution because there seems to be a need and I wanted to contribute the the excellent resource that is Stack Overflow.