The list remove operation should be noted where

Source: Internet
Author: User
Tags concurrentmodificationexception

Import java.util.*;
Public class Object {
public static void Main (string[] args) {
String str1 = new String ("ABCDE");
String str2 = new String ("ABCDE");
String str3 = new String ("ABCDE");
String STR4 = new String ("ABCDE");
String STR5 = new String ("ABCDE");
List List = new ArrayList ();
List.add (STR1);
List.add (STR2);
List.add (STR3);
List.add (STR4);
List.add (STR5);
System.out.println ("list.size () =" + list.size ());
for (int i = 0; i < list.size (); i++) {
if (((String) list.get (i)). StartsWith ("ABCDE")) {
List.remove (i);
}
}
System.out.println ("after remove:list.size () =" + list.size ());
}
}

The run result is not:

List.size () =5
After Remove:list.size () =0

It's actually:

List.size () =5
After Remove:list.size () =2

Cause: After each removal of the list, the elements behind will move forward, and if the i=i+1 is executed, the elements that have just been moved are not read.

Workaround:

1. Traverse List backwards

for (int i = List.size ()-1; i > =0; i--) {
if (((String) list.get (i)). StartsWith ("ABCDE")) {
List.remove (i);
}
}

2. Move I back after each element is removed

for (int i = 0; i < list.size (); i++) {
if (((String) list.get (i)). StartsWith ("ABCDE")) {
List.remove (i);
I=i-1;

}
}

3. Use the Iterator.remove () method to delete

for (Iterator it = List.iterator (); It.hasnext ();) {
String str = (string) it.next ();
if (Str.equals ("Chengang")) {
It.remove ();
}
}

Note: In traversing the list or in the process of traversing the collection, the delete action will be the error


I met a concurrentmodificationexception in my work. The code is as follows:
List List = ...;
for (Iterator iter = List.iterator (); Iter.hasnext ();) {
Object obj = Iter.next ();
...
if (* * *) {
List.remove (obj);
}
}
When the Remove method is executed, and then the loop is executed, the Iter.next () is reported java.util.ConcurrentModificationException (of course, if the remove is the last one, it will not be executed next ( ) was operated)

Let's take a look at the source
Public interface Iterator<e> {
Boolean hasnext ();
E next ();
void Remove ();
}

Public interface Collection<e> extends iterable<e> {
...
Iterator<e> iterator ();
Boolean Add (E o);
Boolean remove (Object O);
...
}
Here are two remove methods

Next look at Abstractlist
Public abstract class Abstractlist<e> extends abstractcollection<e> implements list<e> {
Abstractcollection and List both inherited collection.
protected transient int modcount = 0;
Private class Itr implements Iterator<e> {//inner class ITR
int cursor = 0;
int lastret =-1;
int expectedmodcount = Modcount;

public Boolean hasnext () {
return cursor!= size ();
}

Public E Next () {
Checkforcomodification (); Pay special attention to this method
try {
E next = get (cursor);
Lastret = cursor++;
return to Next;
catch (Indexoutofboundsexception e) {
Checkforcomodification ();
throw new Nosuchelementexception ();
}
}

public void Remove () {
if (Lastret = = 1)
throw new IllegalStateException ();
Checkforcomodification ();

try {
AbstractList.this.remove (Lastret); Performing actions on the Remove object
if (Lastret < cursor)
cursor--;
Lastret =-1;
Expectedmodcount = Modcount; Reset the value of the Expectedmodcount to avoid the generation of concurrentmodificationexception
catch (Indexoutofboundsexception e) {
throw new Concurrentmodificationexception ();
}
}

final void Checkforcomodification () {
if (modcount!= expectedmodcount)//When Expectedmodcount and modcount are not equal, throw concurrentmodificationexception
throw new Concurrentmodificationexception ();
}
}
}

The Remove (Object O) is implemented in ArrayList as follows:
public boolean remove (Object o) {
if (o = = null) {
for (int index = 0; index < size; index++)
if (elementdata[index] = = null) {
Fastremove (index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (O.equals (Elementdata[index])) {
Fastremove (index);
return true;
}
}
return false;
}
private void Fastremove (int index) {
modcount++; Only added Modcount.
....
}

So, the reason for the concurrentmodificationexception is:
After the Remove (Object O) method is executed, Modcount and expectedmodcount are not equal. Then when the code executes to the next () method, the Checkforcomodification () is judged, and two values are found, and the exception is thrown.
To avoid this exception, you should use the Remove () method.
Here we do not look at the Add (Object O) method, but also the same reason, but there is no corresponding add () method. In general, we'll build another list.


The following are some of the other explanations on the web that explain the reasons in essence:
Iterator is working in a separate thread and has a mutex lock. Iterator is created to create a single chain index table that points to the original object, and when the original number of objects changes, the contents of this index table will not be synchronized, so when the index pointer moves back, you can't find the object to iterate, so follow the fail-fast principle iterator Will throw the java.util.ConcurrentModificationException exception immediately.
So iterator is not allowed to be changed by the object of the iteration at work. But you can use iterator's own method remove () to delete an object, and the Iterator.remove () method maintains the consistency of the index while deleting the current iteration object.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.