我正在尝试迭代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();
}
}
答案 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();
}
}