2016-01-23 1 views
1

У меня есть этот код.
Я знаю, что это должно дать мне ConcurrentModificationException
, и я должен использовать итератор или клонировать список или просто использовать для цикла.
java list java.util.ConcurrentModificationException

Проблема в том, что этот код работает без проблем, а ls.remove работает с любым индексом между 0-2.
Теперь если я изменить s.equals («два») к s.equals («один») или что-нибудь еще из списка, кроме «двух»
Я всегда буду получать ConcurrentModificationException, как и ожидалось.

Также, если я раскомментирую строку ls.add («four»), у меня всегда будет ConcurrentModificationException, независимо от того, что s.equals() be.

И мои вопросы, почему это происходит, и почему код ниже работает отлично, без ConcurrentModificationException только для s.equals ("two")?

import java.util.*; 
import java.util.List; 

    public class Test { 

    public static void main(String args[]) { 

     List<String> ls = new ArrayList<>(); 

     ls.add("one"); 
     ls.add("two"); 
     ls.add("three"); 
     //ls.add("four"); 

     for(String s : ls) { 
      if(s.equals("two")) { 
       ls.remove(0); 
       //ls.remove("three"); 
      } 
     } 

     System.out.println(ls.size()); 

    } 

} 

и выход

Exception in thread "main" java.util.ConcurrentModificationException 
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) 
at java.util.ArrayList$Itr.next(ArrayList.java:851) 
at Test.main(Test.java:15) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at  sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl. java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 
+0

Вы не можете изменить список, когда вы повторяете его. И «ConcurrentModificationException» не гарантируется. –

+1

Дубликат http://stackoverflow.com/questions/8189466/java-util-concurrentmodificationexception –

ответ

1

Вы не должны изменять список пока переборе над ним. Итератор может (или не может) терпеть неудачу, в зависимости от реализации. Поэтому удаление некоторых элементов в части списка может работать, другие - нет. Способом сохранения этой проблемы является использование метода удаления итераторов или использование CopyOnWriteArrayList или любой другой коллекции, поддерживающей такую ​​модификацию.