Как исправить ошибку java.util.ConcurrentModificationException при попытке пройти в ArrayList

Я пытаюсь добавить новый объект в мой ArrayList, если он удовлетворяет условию. Но я получил это ConcurrentModificationExeption, когда я попытался запустить его. Надеюсь, вы могли бы помочь мне:

<code>public void addTaskCollection(Task t){ 
    ListIterator<Task> iterator = this.taskCollection.listIterator();
    if(this.taskCollection.isEmpty())
        this.taskCollection.add(t);
    while (iterator.hasNext()){
        if(t.isOverlapped(iterator.next()))
            this.taskCollection.add(t);
    }    
}
</code>

И здесь ошибка исключения

<code>Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at Diary.addTaskCollection(Diary.java:36)
at Test.main(Test.java:50)
Java Result: 1
</code>
 Tiago Peczenyj11 мая 2012 г., 08:19
Collections.copy (судьба, источник)
 Balaswamy Vaddeman11 мая 2012 г., 08:15

Ответы на вопрос(4)

вы столкнулись с расой. Несколько потоков получают доступ к одной и той же коллекции. Используйте потокобезопасную реализацию List.

Кроме того, вы не должны изменять коллекцию (добавлять / удалять), когда выполняете ее итерацию.

EDIT

ConcurrentModificationExeption Похоже, что TaskCollection доступен и модифицируется несколькими потоками одновременно (мы не можем сказать, какой кусок кода вы предоставляете, если ваша программа является однопоточной или многопоточной). Если вы разделяете taskCollection между несколькими потоками, используйте поточно-ориентированную реализацию списка.

Но ошибка здесь на самом деле очевидна из-за того, что вы добавляете элемент в коллекцию между моментом, когда вы получаете на него итератор, и моментом, когда вы используете этот итератор. Чтобы исправить это, скопируйте новые элементы во временный список и добавьте их все сразу в конце итерации.

 babygau11 мая 2012 г., 08:22
Так, как я мог изменить вышеупомянутый arraylist, заботясь, чтобы просветить меня?
 11 мая 2012 г., 08:28
Это неправильно ... эта программа однопоточная.
 11 мая 2012 г., 08:29
Проблема только в том, что вы не можете изменить список, перебирая его с помощью итератора ... вот почему вы должны скопировать его и изменить копию.
 11 мая 2012 г., 10:10
Вы не знаете, что он многопоточный. Это вполне может быть однопоточным
 11 мая 2012 г., 09:02
Во-первых, у вас недостаточно информации, чтобы сказать, что программа однопоточная. В любом случае, мы все согласны с тем, что ошибка связана с итерацией / модификацией, и вы вправе указать, что мой пост был неясным. Так что я только что отредактировал это. Во-вторых, вот javadoc для ConcurrentModificationException: & quot; ... как правило, один поток не может изменять коллекцию, пока другой поток итерирует по ней. Как правило, результаты итерации в этих обстоятельствах не определены ... & quot;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Example_v3 {

     public static void main(String[] args) {
          List<String> list = new ArrayList<String>();

          // Insert some sample values.
          list.add("Value1");
          list.add("Value2");
          list.add("Value3");

          // Get two iterators.
          Iterator<String> ite = list.iterator();
          Iterator<String> ite2 = list.iterator();

          // Point to the first object of the list and then, remove it.
          ite.next();
          ite.remove();

          /* The second iterator tries to remove the first object as well. The object does
           * not exist and thus, a ConcurrentModificationException is thrown. */
          ite2.next();
          ite2.remove();
     }
}

ListIterator<Task> iterator = this.taskCollection.listIterator();
boolean marker = false;

if(taskCollection.isEmpty())
  this.taskCollection.add(t);
else {
  while (iterator.hasNext()) {
    if(iterator.next().isOverlapped(t) == false)
      marker = true;
  }
  if (marker == true)
    taskCollection.add(t);
}
Решение Вопроса

ListIterator<Task> iterator = this.taskCollection.listIterator();
boolean marker = false;

if(taskCollection.isEmpty())
    this.taskCollection.add(t);
else {
   while (iterator.hasNext()) {
      if(iterator.next().isOverlapped(t) == false)
         marker = true;
   }
}

if (marker == true)
    taskCollection.add(t);

чтобы избежать ConcurrentModificationException.

 babygau11 мая 2012 г., 09:20
Да, и я попытался немного изменить ваш код, чтобы он был скомпилирован, но вывод неправильный.
 11 мая 2012 г., 08:40
Вы все еще получаете ConcurrentModificationException?
 babygau11 мая 2012 г., 08:39
Это не работает, приятель & gt;. & Lt;
 babygau11 мая 2012 г., 09:26
Потому что ваш ответ довольно близок к моему вопросу, поэтому я буду отмечать вас как правильный ответ.
 babygau11 мая 2012 г., 09:25
Я наконец-то понял все правильно, но у меня недостаточно прав, чтобы ответить на мой вопрос. Если возможно, пожалуйста, помогите мне изменить обновление вашего кода следующим образом: & lt; / br & gt;ListIterator<Task> iterator = this.taskCollection.listIterator(); boolean marker = false; if(taskCollection.isEmpty()) this.taskCollection.add(t); else{ while (iterator.hasNext()){ if(iterator.next().isOverlapped(t) == false) marker = true; } if (marker == true) taskCollection.add(t); }

Ваш ответ на вопрос