ConcurrentModificationException 在执行 Set 的 addAll 操作时发生。

huangapple go评论78阅读模式
英文:

ConcurrentModificationException when I do a addAll for a Set

问题

我在下面的代码中遇到了ConcurrentModificationException异常,发生在allStates.addAll(states)这一行。我该如何避免这个问题?

public synchronized Set<String> getAllStates(String clientName, Map<String, Set<String>> allClientStates) {
    Set<String> allStates = new ConcurrentSkipListSet<>();
    final Set<String> keySet = allClientStates.keySet();
    for(String key: keySet) {
      Set<String> states = allClientStates.get(key);
      if(states != null)
        allStates.addAll(states);
    }
    return allStates;
  }

这是堆栈跟踪的顶部部分:

exception: null
java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextNode(HashMap.java:1445)
    at java.util.HashMap$KeyIterator.next(HashMap.java:1469)
    at java.util.AbstractCollection.addAll(AbstractCollection.java:343)
    at com.xxx.config.ClientDashboardConfig.getAllStates(ClientDashboardConfig.java:312)
英文:

I get a concurrentModificationException at allStates.addAll(states) in the code below. How can I avoid this?

public synchronized Set&lt;String&gt; getAllStates(String clientName, Map&lt;String, Set&lt;String&gt;&gt; allClientStates) {
    Set&lt;String&gt; allStates = new ConcurrentSkipListSet&lt;&gt;();
    final Set&lt;String&gt; keySet = allClientStates.keySet();
    for(String key: keySet) {
      Set&lt;String&gt; states = allClientStates.get(key);
      if(states != null)
        allStates.addAll(states);
    }
    return allStates;
  }

This is the top of the stacktrace

exception&quot;: &quot;null\njava.util.ConcurrentModificationException\n\tat java.util.HashMap$HashIterator.nextNode(HashMap.java:1445)\n\tat java.util.HashMap$KeyIterator.next(HashMap.java:1469)\n\tat java.util.AbstractCollection.addAll(AbstractCollection.java:343)\n\tat com.xxx.config.ClientDashboardConfig.getAllStates(ClientDashboardConfig.java:312)

答案1

得分: 2

allClientStates.values().stream()
    .flatMap(keys -> keys.stream())
    .collect(Collectors.toSet());
英文:
allClientStates.values().stream()
    .flatMap(keys -&gt; keys.stream())
    .collect(Collectors.toSet());

答案2

得分: 0

我不明白为什么需要ConcurrentSkipListSet和clientName。这段代码是否完整?

另外,不清楚是否有JVM版本限制。

使用Java 8,你可以这样做:

allClientStates.values()
.stream()
.flatMap(Collection::stream)
.collect(Collectors.toSet());
英文:

I didn't get why do you need the ConcurrentSkipListSet and the clientName. Is this code complete?

Also not clear if there's JVM version limitation

Using java 8 you can do like this:

allClientStates.values()
.stream()
.flatMap(Collection::stream)
.collect(Collectors.toSet());

huangapple
  • 本文由 发表于 2020年8月11日 10:31:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63350664.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定