【问题标题】:How to Avoid ConcurrentModificationException in that case?在这种情况下如何避免 ConcurrentModificationException?
【发布时间】:2019-10-22 06:04:56
【问题描述】:

我了解,当我尝试修改(在这种情况下添加)列表时,我得到了 ConcurrentModificationException,但是解决此问题的最佳解决方案是什么?

for (Map.Entry<String, Child> entry : children.entrySet() {
     childEvent.child = entry.getValue();
     if (childEvent.getDate() != null && childEvent.getDate().equals(selectedDate)) {
         if(this.selectedDayevents.isEmpty()) {
             // List                                
             this.selectedDayevents.add(childEvent);
          }
         for (CareDay selectedCareDay : this.selectedDayevents) {
             // Here I have to combine data in some cases...
         }
     }  
}

【问题讨论】:

  • 在另一个Map 中收集更改,然后在遍历条目后使用Map.addAll
  • 但是我需要在第二个 for 循环中将数据添加到 CareDay-objects,所以我认为将每个更改的对象收集到第三个 List、Map 等并不是解决方案,然后我必须循环那些(我认为)
  • 如果您需要在迭代过程中修改列表 - 使用此列表 Iteratoraddremove 元素或创建新列表并添加/删除它。
  • 请在您的minimal reproducible example 中显示失败代码。显然,您展示的 add 声明不是失败的声明?在这种情况下,您应该删除它以使示例 minimal ,并请添加语句 this is 失败。另外请正确缩进代码 - 现在几乎不可能阅读它。

标签: java list for-loop concurrentmodification


【解决方案1】:

解决此问题的一种简单方法是遍历条目集的副本

for (Map.Entry<String, Child> entry : new HashSet<>(children.entrySet())) {
    // same code
}

如果您的地图不是太大并且您不经常这样做,您不会注意到性能差异。

【讨论】:

    【解决方案2】:

    如果您的要求是启用对集合的并发访问,那么您应该探索 java 并发 API,尤其是 ConcurrentHashMapConcurrentSkipListMap 适合您的情况。

    【讨论】:

    • OP 没有提到任何与并发访问相关的内容。如果您想向 OP 提问,请在您有足够声望的情况下使用 cmets。
    • 欧文,我的回答显然是从“如果您的要求是……”开始的,因此明确提到了答案的必要条件性质。
    猜你喜欢
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 2013-07-17
    • 2014-08-24
    相关资源
    最近更新 更多