FelixF
FelixF

Reputation: 83

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

Upvotes: 1

Views: 2584

Answers (3)

yetsun
yetsun

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

Michael Koch
Michael Koch

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

ParkerHalo
ParkerHalo

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

Related Questions