Search code examples
javaloopsguavamultimap

Java Guava: Iterating and removing keys of Multimap


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

Solution

  • 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().