【问题标题】:ConcurrentModificationException in unmodifiable collection [duplicate]不可修改集合中的 ConcurrentModificationException [重复]
【发布时间】:2013-11-12 15:05:27
【问题描述】:

我在下面有这段代码,我通过执行以下行得到了 ConcurrentModificationException:

filterCardsToDevice(getCollection());

代码:

private List<MyClass> filterCardsToDevice(Collection<MyClass> col) {
    final List<MyClass> newList = new ArrayList<MyClass>();

    for (MyClass myObj : col) {
        long id = myObj.getId();
        if (id < 0 || id > 0xFFFFFFFFl) {
            // just a log here
        } else {
            newList.add(myObj);
        }
    }

    return newList;
}

private final Map<Long, MyClass> map = new HashMap<Long, MyClass>();

public Collection<MyClass> getCollection() {
    synchronized (map) {
        return Collections.unmodifiableCollection(map.values());
    }
}

堆栈是:

at java.util.HashMap$HashIterator.nextEntry(HashMap.java:841)                 
at java.util.HashMap$ValueIterator.next(HashMap.java:871)                 
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010)

正好在 foreach 行:

for (MyClass myObj : col) {

我不明白为什么会出现这个错误,因为我没有修改列表。

【问题讨论】:

  • 这不是重复的,这是专门要求不可修改的集合

标签: java collections concurrentmodification unmodifiable


【解决方案1】:

请注意,Collections.unmodifiable*不会复制集合数据,而只是将原始集合包装在一个特殊的包装器中。所以如果你修改原来的集合,就会报这个错误。


如果你想创建真正独立的不可修改的集合实例:

Collections.unmodifiableCollection(new ArrayList<>(map.values()));

【讨论】:

    【解决方案2】:

    当您迭代 col 时,您必须在另一个线程中更新 mapmap#valuesCollections.unmodifiableCollection 都返回现有数据结构的视图,因此您正在迭代(这由您的堆栈跟踪见证)是您的 map 的条目集。

    【讨论】:

      猜你喜欢
      • 2014-09-01
      • 2012-02-12
      • 2016-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多