【问题标题】:Iterate on a Multiset in Java, use setcount() without ConcurrentModificationException在 Java 中迭代 Multiset,使用 setcount() 而不使用 ConcurrentModificationException
【发布时间】:2016-05-22 07:56:23
【问题描述】:
Multiset<String> ngrams = HashMultiset.create();  
//added strings to the multiset...

    for (Entry<String> entry : ngrams.entrySet()) {
       if (entry.getCount() > 3) {
          ngrams.setCount(terms, 3);
       }
    }

抛出ConcurrentModificationException

如何使用setCount() 而不抛出此异常?一些 Java 8 代码在这里有用吗?

【问题讨论】:

  • 您可能不应该在迭代 ngrams 集时对其进行修改。
  • 创建一个新的Multiset&lt;String&gt;ngrams 中的每个条目最多计数 3 个。
  • 此类异常几乎意味着告诉您在迭代该集合时不要修改某种集合。

标签: java guava multiset


【解决方案1】:

如果HashMultiset 中的元素计数为零,setCount(E, int) 只会抛出ConcurrentModificationException

即如果ngrams 已经包含terms,那么更改terms 计数将不会抛出ConcurrentModificationException

例如您可以在迭代之前使用特殊的计数值(例如Integer.MAX_VALUE)添加terms,如果没有更改,则在迭代后将其删除:

Multiset<String> ngrams = HashMultiset.create();
//added strings to the multiset...

    ngrams.setCount(terms, Integer.MAX_VALUE);

    for (Multiset.Entry<String> entry : ngrams.entrySet()) {
        if (entry.getElement().equals(terms)) {
            continue;
        }
        if (entry.getCount() > 3) {
            ngrams.setCount(terms, 3);
        }
    }

    if (ngrams.count(terms) == Integer.MAX_VALUE) {
        ngrams.setCount(terms, 0);
    }

如果您的情况更复杂,那么您最好创建一个新的Multiset&lt;String&gt; 作为Andy Turner suggests,而不是同时修改和迭代。 (或者其他一些不涉及并发迭代修改等的方案)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 2014-05-23
    • 1970-01-01
    • 2012-11-21
    • 2018-05-18
    • 1970-01-01
    相关资源
    最近更新 更多