【问题标题】:Java Guava: Iterating and removing keys of MultimapJava Guava:迭代和删除 Multimap 的键
【发布时间】:2016-02-06 00:41:51
【问题描述】:

我正在尝试遍历 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();
    }
}

【问题讨论】:

    标签: java loops guava multimap


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        您可以遍历地图并将所有要删除的键保存在列表中。

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

        【讨论】:

          猜你喜欢
          • 2015-04-30
          • 2013-05-14
          • 1970-01-01
          • 2021-08-12
          • 1970-01-01
          • 2010-12-07
          • 2012-10-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多