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 wor
It is possible to implement a Set that allows its elements to be removed whilst iterating over it.
I think the standard implementations (HashSet, TreeSet etc.) disallow it because that means they can use more efficient algorithms, but it's not hard to do.
Here's an incomplete example using Google Collections:
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.google.common.base.Predicates;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.Sets;
public class ConcurrentlyModifiableSet
extends ForwardingSet {
/** Create a new, empty set */
public ConcurrentlyModifiableSet() {
Map map = new ConcurrentHashMap();
delegate = Sets.newSetFromMap(map);
}
@Override
public Iterator iterator() {
return Iterators.filter(delegate.iterator(), Predicates.in(delegate));
}
@Override
protected Set delegate() {
return this.delegate;
}
private Set delegate;
}
Note: The iterator does not support the remove() operation (but the example in the question does not require it.)