【问题标题】:ConcurrentModificationException in foreach loop [duplicate]foreach 循环中的 ConcurrentModificationException [重复]
【发布时间】:2014-03-03 22:43:27
【问题描述】:

在我的代码中:

    Collection<String> c = new ArrayList<>();
    Iterator<String> it = c.iterator();
    c.add("Hello");
    System.out.println(it.next());

出现异常,因为我的集合在迭代器创建后发生了变化。

但是在这段代码中呢:

 ArrayList<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    for (Integer integer : list) {     // Exception is here
        if (integer.equals(2)) {
            list.remove(integer);
        }
    }

为什么会出现异常?

在第二个代码中,我在 for-each 循环之前对我的集合进行了更改。

【问题讨论】:

  • 如果 remove() 不修改集合,你会做什么?
  • for-each 使用迭代器。
  • 这个问题似乎离题了,因为它没有显示之前的研究

标签: java collections arraylist concurrentmodification


【解决方案1】:

您还在 for-each 循环中更改您的集合:

  list.remove(integer);

如果您需要在迭代时删除元素,您可以跟踪需要删除的索引并在 for-each 循环完成后删除它们,或者使用允许并发修改的 Collection。

【讨论】:

    【解决方案2】:

    在第二个循环中,原因相同 - 您要从列表中删除一个元素。

    要在循环遍历 List 时删除元素,请使用标准的老式 for 循环:

    for(int i=0;i<list.size();i++) {
    

    并删除该循环内的列表项或使用ListIterator 来遍历列表。

    【讨论】:

      【解决方案3】:

      如果您需要在使用更好的语法进行迭代时删除元素,这是永远不会获得 ConcurrentModificationExceptions 的最干净的方法:

      // utility method somewhere
      public static < T > Iterable< T > remainingIn( final Iterator< T > itT ) {
          return new Iterable< T >() {
              @Override
              public Iterator< T > iterator() {
                  return itT;
              }
          }
      }
      
      // usage example
      Iterator< Integer > itI = list.iterator();
      for ( Integer integer : remainingIn( itI ) ) {
          if ( integer.equals( 2 ) ) {
              itI.remove();
          }
      }
      

      【讨论】:

        【解决方案4】:

        你可以改用CopyOnWriteArrayList,效率不高,但解决了ConcurrentModificationException,你可以安全地使用remove方法。

        【讨论】:

          【解决方案5】:

          例外是因为您正在迭代以及从列表中删除元素

           for (Integer integer : list) {     // Exception is here because you are iterating and also removing the elements of same list here
                  if (integer.equals(2)) {
                      list.remove(integer);
                  }
          

          【讨论】:

            猜你喜欢
            • 2013-09-04
            • 2012-04-06
            • 1970-01-01
            • 1970-01-01
            • 2013-02-25
            • 1970-01-01
            • 2014-01-06
            • 1970-01-01
            • 2018-12-11
            相关资源
            最近更新 更多