Java Guava:迭代和删除Multimap的键

时间:2015-11-05 08:56:01

标签: java loops guava multimap

我正在尝试迭代Multimap并根据任意检查删除一些键及其值。

Multimap<Integer, Character> myMultimap = ArrayListMultimap.create();

myMultimap.keySet().stream().forEach((bin) -> {
    if (random.nextDouble() < p) {
        myMultimap.removeAll(bin);
    }
});

这显然会引发ConcurrentModificationException。

所以我试过了:

Iterator<Integer> i = myMultimap.keySet().iterator();
while (i.hasNext()) {
    if (random.nextDouble() < p) {
        i.remove();         
    }
}

但是这会导致java.lang.IllegalStateException:自上次调用remove()以来没有调用next()。 我试着像下面的代码一样玩它,但经过几次迭代后我仍然会得到同样的错误。

Iterator<Integer> i = myMultimap.keySet().iterator();
while (i.hasNext()) {
    if (random.nextDouble() < p) {
        i.remove();
        i.next();
    } else {
        i.next();
    }
}

3 个答案:

答案 0 :(得分:3)

创建迭代器时,它指向之前第一个元素。您必须先调用next(),然后才能调用remove()来推进迭代器(即使您不需要该元素)。 remove()会影响next()调用返回的元素。

答案 1 :(得分:0)

你可以迭代地图并保存所有要删除的键。

Iterator<Integer> i = myMultimap.keySet().iterator();
List<Integer> keyList = new ArrayList<Integer>();
while (i.hasNext()) {
    if (random.nextDouble() < p)
        keyList.add(i);
}

然后从地图中删除列表中的每个条目:

for (Integer key : keyList)
    myMultimap.remove(key);

答案 2 :(得分:0)

正如 Michael Koch 所说,next() 需要在 remove() 之前调用。以下代码应该可以工作。

Iterator<Integer> i = myMultimap.keySet().iterator();
while (i.hasNext()) {
    i.next();
    if (random.nextDouble() < p) { 
        i.remove();
    } 
}