在Java中迭代Multiset,使用setcount()而不使用ConcurrentModificationException

时间:2016-02-11 13:45:34

标签: java guava multiset

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代码在这里有用吗?

1 个答案:

答案 0 :(得分:1)

如果setCount(E, int)中的元素数为零,则

ConcurrentModificationException只会抛出HashMultiset

即。如果ngrams已包含terms,那么更改terms计数将不会引发ConcurrentModificationException

e.g。您可以在迭代前使用特殊计数值(例如terms)添加Integer.MAX_VALUE,然后在迭代后删除它,如果它没有更改:

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<String> Andy Turner suggests,而不是同时修改和迭代。 (或者其他一些不涉及并发迭代和修改的解决方案等)