Reputation: 83
I'm trying to iterate over a Multimap and remove some keys and their values based on a arbitrary check.
Multimap<Integer, Character> myMultimap = ArrayListMultimap.create();
myMultimap.keySet().stream().forEach((bin) -> {
if (random.nextDouble() < p) {
myMultimap.removeAll(bin);
}
});
This obviously throws a ConcurrentModificationException.
So I tried:
Iterator<Integer> i = myMultimap.keySet().iterator();
while (i.hasNext()) {
if (random.nextDouble() < p) {
i.remove();
}
}
This however results in a java.lang.IllegalStateException: no calls to next() since the last call to remove(). I've tried to play around with it like the code below, but I still get the same error after a couple of iterations.
Iterator<Integer> i = myMultimap.keySet().iterator();
while (i.hasNext()) {
if (random.nextDouble() < p) {
i.remove();
i.next();
} else {
i.next();
}
}
Upvotes: 1
Views: 2584
Reputation: 1010
Like Michael Koch said, next()
needs to be called before remove()
. The following code should work.
Iterator<Integer> i = myMultimap.keySet().iterator();
while (i.hasNext()) {
i.next();
if (random.nextDouble() < p) {
i.remove();
}
}
Upvotes: 0
Reputation: 1242
When the iterator is created, it points before the first element. You have to call next()
before you can call remove()
to advance the iterator (even though you don't need the element). remove()
will affect the element which has been returned by the call to next()
.
Upvotes: 4
Reputation: 4430
you could iterate over the map and save all keys to remove in a list.
Iterator<Integer> i = myMultimap.keySet().iterator();
List<Integer> keyList = new ArrayList<Integer>();
while (i.hasNext()) {
if (random.nextDouble() < p)
keyList.add(i);
}
and then remove every entry of the list from the map:
for (Integer key : keyList)
myMultimap.remove(key);
Upvotes: 0