local-host 2008-10-21 23:23 采纳率: 100%
浏览 1289
已采纳

通过集合进行迭代,避免在循环中修改(移除)时的 ConcurrentModificationException

We all know you can't do this:

for (Object i : l) {
    if (condition(i)) {
        l.remove(i);
    }
}

ConcurrentModificationException etc... this apparently works sometimes, but not always. Here's some specific code:

public static void main(String[] args) {
    Collection<Integer> l = new ArrayList<Integer>();

    for (int i=0; i < 10; ++i) {
        l.add(new Integer(4));
        l.add(new Integer(5));
        l.add(new Integer(6));
    }

    for (Integer i : l) {
        if (i.intValue() == 5) {
            l.remove(i);
        }
    }

    System.out.println(l);
}

This, of course, results in:

Exception in thread "main" java.util.ConcurrentModificationException

... even though multiple threads aren't doing it... Anyway.

What's the best solution to this problem? How can I remove an item from the collection in a loop without throwing this exception?

I'm also using an arbitrary Collection here, not necessarily an ArrayList, so you can't rely on get.

转载于:https://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-mo

  • 写回答

21条回答 默认 最新

  • 北城已荒凉 2008-10-21 23:27
    关注

    Iterator.remove() is safe, you can use it like this:

    List<String> list = new ArrayList<>();
    
    // This is a clever way to create the iterator and call iterator.hasNext() like
    // you would do in a while-loop. It would be the same as doing:
    //     Iterator<String> iterator = list.iterator();
    //     while (iterator.hasNext()) {
    for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
        String string = iterator.next();
        if (string.isEmpty()) {
            // Remove the current element from the iterator and the list.
            iterator.remove();
        }
    }
    

    Note that Iterator.remove() is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

    Source: docs.oracle > The Collection Interface


    And similarly, if you have a ListIterator and want to add items, you can use ListIterator#add, for the same reason you can use Iterator#remove — it's designed to allow it.


    In your case you tried to remove from a list, but the same restriction applies if trying to put into a Map while iterating its content.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(20条)

报告相同问题?

悬赏问题

  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办