Получение ConcurrentModificationException брошенного при удалении элемента из списка java.util.List во время итерации? [Дубликат] -- java поле с участием list поле с участием concurrentmodification пол Связанный проблема

Getting a ConcurrentModificationException thrown when removing an element from a java.util.List during list iteration? [duplicate]


60
vote

проблема

русский
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»>
Этот вопрос уже есть ответы здесь :
Итерация через коллекцию, избегая ConcurrentModificationException при удалении объектов в цикле (27 ответов)
Closed <пролет класс = "relativetime" название = "2017-11-16 17: 22: 02Z"> 3 года назад
.
 <код> @Test public void testListCur(){     List<String> li=new ArrayList<String>();     for(int i=0;i<10;i++){         li.add("str"+i);     }      for(String st:li){         if(st.equalsIgnoreCase("str3"))             li.remove("str3");     }     System.out.println(li); }   
<Р> Когда я запускаю этот код, я кину <код> ConcurrentModificationException . <Р> Это выглядит так, как будто, когда я удалить указанный элемент из <код> list , то <код> list не знает его <код> size были изменены. < / р> <Р> Я интересно, если это общая проблема с <код> collections и удаление элементов?
Английский оригинал
@Test public void testListCur(){     List<String> li=new ArrayList<String>();     for(int i=0;i<10;i++){         li.add("str"+i);     }      for(String st:li){         if(st.equalsIgnoreCase("str3"))             li.remove("str3");     }     System.out.println(li); } 

When I run this code,I will throw a ConcurrentModificationException.

It looks as though when I remove the specified element from the list, the list does not know its size have been changed.

I'm wondering if this is a common problem with collections and removing elements?

</div
        

Список ответов

90
 
vote
vote
Лучший ответ
 

Я считаю, что это цель за

 

I believe this is the purpose behind the Iterator.remove() method, to be able to remove an element from the collection while iterating.

For example:

Iterator<String> iter = li.iterator(); while(iter.hasNext()){     if(iter.next().equalsIgnoreCase("str3"))         iter.remove(); } 
</div
 
 
       
       
25
 
vote

Java 8 способ удалить его из списка без итератора:

 <код> li.removeIf(<predicate>)   

I.e.

 <код> List<String> li = new ArrayList<String>(); // ... li.removeIf(st -> !st.equalsIgnoreCase("str3"));   
 

The Java 8 way to remove it from the List without Iterator is:

li.removeIf(<predicate>) 

i.e.

List<String> li = new ArrayList<String>(); // ... li.removeIf(st -> !st.equalsIgnoreCase("str3")); 
</div
 
 
19
 
vote

Обратите внимание, что это исключение не всегда указывает, что объект был одновременно модифицирован другим потоком. Если один поток выдает последовательность вызовов метода, которые нарушают договор объекта, объект может выбросить это исключение. Например, если поток изменяет коллекцию непосредственно во время его итерации по поводу коллекции с Fail-Fast ITERATRATOR, итератор предат это исключение

взяты из http: // скачать. Oracle.com/javase/1.4.2/docs/api/java/util/concurrentModificationException.html

 

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will thow this exception

Taken from http://download.oracle.com/javase/1.4.2/docs/api/java/util/ConcurrentModificationException.html

</div
 
 
6
 
vote

Да, люди бегают в нее - проблема в том, что вы не можете изменять список во время итерации по нему. Я использовал 2 альтернативы в прошлом:

  1. Вы можете отслеживать индексы элементов, которые вы хотите удалить, а затем удалить их после того, как вы закончите итерацию.
  2. Или вы можете скопировать все те, которые вы хотите сохранить в новом списке, так как вы итерации, а затем сбросьте старый список, когда закончите.

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

В вашем конкретном случае вам даже не нужно повторять, как вы можете просто использовать Removeall. Посмотрите на API Здесь . Есть также нефтепользовательские методы, такие как retainall, которые отказываются от всего, что не в аргументе. Вы можете использовать методы удаления / удержания методов всякий раз, когда объекты в списке реализуют равны и правильно хэшкоду. Если вы не можете полагаться на равных / hashcode, чтобы определить равенство между экземплярами в вашем приложении, вам придется сделать удаление себя ....

 

yes people run into it -- the problem is you can't modify the list while iterating over it. I have used 2 alternatives in the past:

  1. You can keep track of the indexes of the items you want to remove, and then remove them after you are done iterating.
  2. Or you can copy all the ones you want to keep into a new list as you iterate, and then discard the old list when done.

those options assume you have to iterate over the list to find the elements to remove -- useful in cases where the list elements are complex objects with properties you might test on.

In your particular case, you dont even need to iterate, as you can just use removeAll. Look at the API here. There are also nifty methods like retainAll that discard everything that is not in the argument. You can use remove/retain-like methods whenever the objects in the list implement equals and hashcode properly. If you cannot rely on equals/hashcode to identify equality between instances in your app, you will have to do the removal yourself....

</div
 
 
3
 
vote

Вы можете сделать копию списка, которую вы хотите удалить элемент, непосредственно в каждом контуре. Для меня это самый простой способ. Что-то вроде этого:

 <код> for (String stringIter : new ArrayList<String>(myList)) {     myList.remove(itemToRemove); }   

Надеюсь, что поможет вам ..

 

You could make a copy of list you want to remove element from, directly in for-each loop. For me, that is the simpliest way. Something like this:

for (String stringIter : new ArrayList<String>(myList)) {     myList.remove(itemToRemove); } 

Hope that will help you..

</div
 
 
2
 
vote

Я думаю, стоит упомянуть версию Java 8

 <код> @Test public void testListCur() {     List<String> li = new ArrayList<String>();     for (int i = 0; i < 10; i++) {         li.add("str" + i);     }      li = li.stream().filter(st -> !st.equalsIgnoreCase("str3")).collect(Collectors.toList());      System.out.println(li); }   
 

I think it is worth mentioning the Java 8 version

@Test public void testListCur() {     List<String> li = new ArrayList<String>();     for (int i = 0; i < 10; i++) {         li.add("str" + i);     }      li = li.stream().filter(st -> !st.equalsIgnoreCase("str3")).collect(Collectors.toList());      System.out.println(li); } 
</div
 
 
 
 
2
 
vote

Попробуйте это (Java 8):

 <код> list.removeIf(condition);   
 

Try this (Java 8):

list.removeIf(condition); 
</div
 
 
1
 
vote

ArrayList имеет поле <код> modCount - Подсчет модификаций сбора

Когда вы вызываете метод <код> iterator() создает новый объект <код> Itr . Имеет поле <код> expectedModCount . <Код> expectedModCount Поле инициализируют на modCount значение. Когда вы вызываете

 <код> li.remove("str3");   

<Код> @Test public void testListCur() { List<String> li = new ArrayList<String>(); for (int i = 0; i < 10; i++) { li.add("str" + i); } li = li.stream().filter(st -> !st.equalsIgnoreCase("str3")).collect(Collectors.toList()); System.out.println(li); } 0 Приращения. Когда вы попробуйте доступ к <код> @Test public void testListCur() { List<String> li = new ArrayList<String>(); for (int i = 0; i < 10; i++) { li.add("str" + i); } li = li.stream().filter(st -> !st.equalsIgnoreCase("str3")).collect(Collectors.toList()); System.out.println(li); } 1 через iTerator Учитывает, что <код> @Test public void testListCur() { List<String> li = new ArrayList<String>(); for (int i = 0; i < 10; i++) { li.add("str" + i); } li = li.stream().filter(st -> !st.equalsIgnoreCase("str3")).collect(Collectors.toList()); System.out.println(li); } 2

И если это ложные броски <код> @Test public void testListCur() { List<String> li = new ArrayList<String>(); for (int i = 0; i < 10; i++) { li.add("str" + i); } li = li.stream().filter(st -> !st.equalsIgnoreCase("str3")).collect(Collectors.toList()); System.out.println(li); } 3

Следовательно, если вы получите итератор и после модифицированного сбора - ITERATOR считается недействительным, и вы не можете его использовать.

 

ArrayList has field modCount - count of collection modifications

When you invoke method iterator() creates new object Itr. It has field expectedModCount. expectedModCount field initialize by modCount value. When you invoke

li.remove("str3"); 

modCount increments. When do you try access to li via iterator checks that expectedModCount == modCount

and if it is false throws ConcurrentModificationException

Hence if you get iterator and after collection modified - iterator is considered not valid and you cannot use it.

</div
 
 
0
 
vote

Я получил эту проблему, и я думаю, что более простой способ, одинаково со вторым образом, что HVGotcodes дал.

Или вы можете скопировать все те, которые вы хотите сохранить в новом списке, так как вы повторяете, а затем сбросьте старый список, когда закончите.

 <код> @Test public void testListCur() {     List<String> li = new ArrayList<String>();     for (int i = 0; i < 10; i++) {         li.add("str" + i);     }      li = li.stream().filter(st -> !st.equalsIgnoreCase("str3")).collect(Collectors.toList());      System.out.println(li); } 4  
 

I got this problem and I think the easier way is the same with the second way that hvgotcodes gave.

Or you can copy all the ones you want to keep into a new list as you iterate, and then discard the old list when done.

@Test public void testListCur(){     List<String> li=new ArrayList<String>();     for(int i=0;i<10;i++){         li.add("str"+i);     }     List<String> finalLi = new ArrayList<String>();     for(String st:li){         if(st.equalsIgnoreCase("str3")){             // Do nothing         } else {             finalLi.add(st);         }     }     System.out.println(finalLi); } 
</div
 
 
0
 
vote

Я запланировал по-другому ...

 <код> public void testListCur(){     List<String> li=new ArrayList<String>();     for(int i=0;i<10;i++){         li.add("str"+i);     }      for(int i=0; i<li.size(); i++)         if(li.get(i).equalsIgnoreCase("str3"))             li.remove(i--);      System.out.println(li); }   
 

I looped a different way...

public void testListCur(){     List<String> li=new ArrayList<String>();     for(int i=0;i<10;i++){         li.add("str"+i);     }      for(int i=0; i<li.size(); i++)         if(li.get(i).equalsIgnoreCase("str3"))             li.remove(i--);      System.out.println(li); } 
</div
 
 
0
 
vote

Я думаю, что лучший ответ от BigDev.de, но я хотел бы добавить что-то к нему (например, если элемент удален из списка, может быть, вы хотели бы войти в систему где-то или что-то):

 <Код> List<String> list = new ArrayList<>();  list.removeIf(a -> {                 boolean condition = a.equalsIgnoreCase("some condition");                 if(condition)                     logger.info("Item removed from the list: " + a);                 return condition;   });   
 

I think that best answer is from bigdev.de, but i would like to add something to it(like if the item is removed from a list, maybe you would like to log that somewhere or something):

List<String> list = new ArrayList<>();  list.removeIf(a -> {                 boolean condition = a.equalsIgnoreCase("some condition");                 if(condition)                     logger.info("Item removed from the list: " + a);                 return condition;   }); 
</div
 
 

Связанный проблема

1  Реализация интерфейса Realmmodel при расширении другого объекта  ( Implementing realmmodel interface while extending another object ) 
Я хочу использовать новую функцию realm-java, где я могу просто реализовать интерфейс Realmmodel и добавить аннотацию @realmclass для определения таблицы. Все...

5  Конвенции о ведении регистрации [Закрыто]  ( Logging conventions ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> <Путь d = "M15 6.38A6.48 6.48 0 007.78. 04H-.02A6.49 6.49 0 002.05 ...

0  Должен ли я использовать Mac для разработки Javafx для iOS  ( Do i have to use a mac to develop javafx for ios ) 
Документация http://docs.gluonhq.com/charm/4.0.1 / # _ iOS говорит, что мне нужно «Mac с MacOS X 10.9 или превосходящим» для разработки для iOS. Но я не пон...

1  Как вызвать мой метод reзов API, интегрированный с Redis на Windows?  ( How to invoke my restful api method integrated with redis on windows ) 
Я пытаюсь запустить образец весеннего загрузочного приложения с Redis. Я использую завод соединения JEDIS и установив его на заводе подключения шаблона Redis....

3  Как мне изменить ответ на запрос на параметры http в приложении Spring MVC 2.5?  ( How do i change the response for a http options request in a spring mvc 2 5 appl ) 
Это звучит как тривиальный вопрос, но каким-то образом я не могу понять это. У меня есть приложение Spring MVC. Я не поддерживаю никаких HTTP-методов, кроме...

1  Установка поля _ID с использованием SQLite & ContentProvider в Android  ( Setting the id field using sqlite contentprovider in android ) 
Я пытаюсь настроить ContentProvider в приложении Android, чтобы держать информацию о домах. Я хотел бы иметь возможность установить поле _id, чтобы быть таким...

1  Apache Vamel: Как проверить, например, набор набора <customObject>  ( Apache camel how to test for instance of setcustomobject ) 
Кто-нибудь знает, как тестировать для различных типов коллекции в маршруте? <код> // This processor returns a Collection of 2 Sets // 1. Set<GoodMessage> //...

0  Android Studio Back Button  ( Android studio back button problems ) 
на данный момент. Я создал простое приложение для викторины на Android Studio. Все работает нормально, в том числе, когда я иду от первой фактической жизни. Я...

3  Eclipse Java Formatter - новая линия до закрытия скобок  ( Eclipse java formatter newline before closing parentheses ) 
Можно ли настроить Dippleter Eclipse Java для вставки новой строки до закрытия скобок выражений, деклараций метода и вызовы методов? Обратите внимание на же...

22  Множественные методы постконструкции?  ( Multiple postconstruct methods ) 
Он говорит в Документация Java для Postconstruct что Только один метод может быть аннотирован с этой аннотацией Но я просто пытался аннотировать три м...

0  Как удалить нынешние barchart (jfreechart), отображаемый и отображаю новый Barchart в том же представлении плагина Eclipse RCP?  ( How to delete the present barchartjfreechart displayed and display new barchar ) 
Я создаю Barchart с видом на плагин RCP. Данные, которые будут отображаться на графике, поставляется из файла базы данных SQLite3. Код, который я написал, ото...

21  Тип несоответствия для генеральных классов  ( Type mismatch for class generics ) 
У меня есть следующий код, который не скомпировался, и хотя есть способ сделать его компиляцией, я хочу понять, почему он не компилирует. Может ли кто-нибудь ...

0  Класс libgdx не рисует текстуру  ( Libgdx class does not draw texture ) 
Я пытаюсь нарисовать игровой символ в моем классе "MaigaMestreen.java" из класса "Mavans.java", когда я касаюсь экрана моего телефона. К сожалению, моя прогр...

-1  Нужно упростить логическое выражение (байт, короткое, целое число) Java  ( Need to simplify logical expression byte short integer java ) 
Мне нужно упростить выражение Первое выражение <код> (byte)( (short)((short)( (byte)((theInt >> 8) & 0xFF) & 0xFF) + 128) & 0xFF); второе выражение ...

17  Перегрузка Java VS переопределения  ( Java overloading vs overriding ) 
Привет, я просто хочу убедиться, что у меня есть эти понятия правильно. Перегрузка в Java означает, что у вас может быть конструктор или метод с различным кол...

Связанный проблема

1  Реализация интерфейса Realmmodel при расширении другого объекта 
5  Конвенции о ведении регистрации [Закрыто] 
0  Должен ли я использовать Mac для разработки Javafx для iOS 
1  Как вызвать мой метод reзов API, интегрированный с Redis на Windows? 
3  Как мне изменить ответ на запрос на параметры http в приложении Spring MVC 2.5? 
1  Установка поля _ID с использованием SQLite & ContentProvider в Android 
1  Apache Vamel: Как проверить, например, набор набора <customObject> 
0  Android Studio Back Button 
3  Eclipse Java Formatter - новая линия до закрытия скобок 
22  Множественные методы постконструкции? 
0  Как удалить нынешние barchart (jfreechart), отображаемый и отображаю новый Barchart в том же представлении плагина Eclipse RCP? 
21  Тип несоответствия для генеральных классов 
0  Класс libgdx не рисует текстуру 
-1  Нужно упростить логическое выражение (байт, короткое, целое число) Java 
17  Перегрузка Java VS переопределения