How do I delete a list element while traversing it?

Source: Internet
Author: User
Tags arrays concurrentmodificationexception

Reprinted from: "Https://blog.csdn.net/hustwht/article/details/52181810"

"https://blog.csdn.net/superxlcr/article/details/51534428"




The common three ways to traverse the list use the normal for loop traversal using the iterator traversal using the enhanced for loop traversal

for the thread insecure ArrayList class, how to implement it.

Method 1: "Success, but the deletion will change the index index and size of the list, may cause some access to cross over the duration of the problem, so not particularly recommended"

public class Main {public  
    static void Main (string[] args) throws Exception {  
        list<integer> List = new Array List<> ();  
        for (int i = 0; i < 5; i++)  
            list.add (i);  
        List {0, 1, 2, 3, 4} for  
        (int i = 0; i < list.size (); i++) {  
            //index and number  
            System.out.print (i +) "+ list.get (i));  
            if (list.get (i)% 2 = = 0) {  
                list.remove (List.get (i));  
                System.out.print ("delete");  
                i--; Index changes!  Otherwise the output does not match the expected result 
            }  
            System.out.println ();}  
    }}  
  

Method 2: "Report an exception, the first one will be deleted normally, and then call Remove (), the Java.util.C_M_E exception will be reported"

public class Main {public  
    static void Main (string[] args) throws Exception {  
        list<integer> List = new Array List<> ();  
        for (int i = 0; i < 5; i++)  
            list.add (i);  
        List {0, 1, 2, 3, 4} for  
        (Integer num:list) {  
            //index and number  
            System.out.print (num);  
            if (num% 2 = = 0) {  
                list.remove (num);  
                System.out.print ("delete");  
            }  
            System.out.println ();}}}  
  

Method 3: "Succeeded, call the Remove () method of the iterator, instead of the inner class of the collection of Remove ()"

public class Main {public  
    static void Main (string[] args) throws Exception {  
        list<integer> List = new Array List<> ();  
        for (int i = 0; i < 5; i++)  
            list.add (i);  
        List {0, 1, 2, 3, 4}  
        iterator<integer> it = List.iterator ();  
        while (It.hasnext ()) {  
            //index and number  
            int num = It.next ();  
            System.out.print (num);  
            if (num% 2 = = 0) {  
                it.remove ();  
                System.out.print ("delete");  
            }  
            System.out.println ();}}}  
  
So what about the Copyonwritearraylist class for thread safety.


Method 1: "Same as ArrayList"

public class Main {public  
    static void Main (string[] args) throws Exception {  
        list<integer> List = new Copyo Nwritearraylist<> ();  
        for (int i = 0; i < 5; i++)  
            list.add (i);  
        List {0, 1, 2, 3, 4} for  
        (int i = 0; i < list.size (); i++) {  
            //index and number  
            System.out.print (i +) "+ list.get (i));  
            if (list.get (i)% 2 = = 0) {  
                list.remove (List.get (i));  
                System.out.print ("delete");  
                i--; Index changes!  
            }  
            System.out.println ();}}}  
  

Method 2: "Success, unlike ArrayList, because the copy---list is designed to ensure that he can avoid c_m_e anomalies."

public class Main {public  
    static void Main (string[] args) throws Exception {  
        list<integer> List = new Copyo Nwritearraylist<> ();  
        for (int i = 0; i < 5; i++)  
            list.add (i);  
        List {0, 1, 2, 3, 4} for  
        (Integer num:list) {  
            //index and number  
            System.out.print (num);  
            if (num% 2 = = 0) {  
                list.remove (num);  
                System.out.print ("delete");  
            }  
            System.out.println ();}}}  
  

Method 3: "Error, java.lang.UnsupportedOperationException"

A: Unlike ArrayList, because Copyonwritearraylist's iterator is a "snapshot" of its list, it is immutable and cannot be deleted using iterator traversal.

public class Main {public  
    static void Main (string[] args) throws Exception {  
        list<integer> List = new Copyo Nwritearraylist<> ();  
        for (int i = 0; i < 5; i++)  
            list.add (i);  
        List {0, 1, 2, 3, 4}  
        iterator<integer> it = List.iterator ();  
        while (It.hasnext ()) {  
            //index and number  
            int num = It.next ();  
            System.out.print (num);  
            if (num% 2 = = 0) {  
                it.remove ();  
                System.out.print ("delete");  
            }  
            System.out.println ();}}}  
  
In summary, when using ArrayList, we can use iterator to implement the traversal delete, and when we use the copyonwritearraylist, we use the enhanced for loop to iterate the delete, at this time using the iterator traversal delete instead of the problem.


Add:

In Java, when a list is traversed, it throws a java.util.ConcurrentModificationException error if it is modified.
eg: when the main thread traverses the list, the child threads add elements to the list. If you want to ensure that the element is added to the list while traversing. Copyonwritearraylist.
Q: Copyonwritearraylist is guaranteed to be thread-safe, why.
A: Copyonwritearraylist processing writes (including add, remove, set, and so on) is the first to generate a new array with the original data through the JDK1.6 arrays.copyof (), and then write on the new data object, After writing the original reference to the current data object (the application of common sense 1), so that every write is on the new object (because to ensure the consistency of writing, here to a variety of write operations to add a lock, JDK1.6 here with a re-entry lock).
This reads the operation very quickly is very safe, is suitable in the multi-threaded use, absolutely does not occur concurrentmodificationexception.
Conclusion: Copyonwritearraylist is suitable for scenarios where read operations are much larger than write operations, such as caching.
Another way to avoid adding synchronization code but to avoid concurrent modification problems, build a new list in the dispatch task, and then assign the references to the list to the new list.

to better understand the ArrayList traversal, delete the element and add an instance.

public static void Main (string[] args) {
arraylist<string> list = new Arraylist<string> (Arrays.aslist (    "A", "B", "C", "D"));
For (Inti=0;i<list.size (); i++) {  list.remove (i);
}
System.out.println (list);//[b,d] output, not the same as expected
}
  public static void Main (string[] args) {
        arraylist<string> list = new Arraylist<string> (Arrays.aslist (" A "," a "," B "," C "," D "));
        for (int i = 0; i < list.size (); i++) {
            if (list.get (i). Equals ("a")) {
                list.remove (i);
            }
        }
        SYSTEM.OUT.PRINTLN (list);//[a,b,c,d] inconsistent with expectations
    }

Q: look at the for (;;) above Loop, which is implemented for a for loop using an iterator. Nonono! look at the following example:

Throws C_m_e exception public
 static void Main (string[] args) {
        arraylist<string> list = new arraylist<string > (Arrays.aslist ("A", "a", "B", "C", "D"));
        for (String s:list) {
             if (s.equals ("a")) {
                  list.remove (s);}}
}
The output is correct, but. Next () must be called before. Remove (). In a foreach loop, the compiler causes. Next () to be called after the element is deleted?? Judge Hasnext ().
///So the concurrentmodificationexception exception is thrown, public
 static void Main (string[] args) {
        arraylist< string> list = new Arraylist<string> (Arrays.aslist ("A", "a", "B", "C", "D"));
        iterator<string>
        iter = List.iterator ();
        while (Iter.hasnext ()) {
        String s = iter.next ();//    if (s.equals ("a")} is called before remove () {    ITER.R    Emove ();   }
       }
}


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.