What happens if the List is deleted while looping? How to solve?

This is a very classic interview question, I believe many job seekers or novice developers have encountered it. This article mainly delves into why list circular deletion throws an exception? How to avoid this situation?

One, enhance the for loop

package com.bootMybatis.demo;

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

/**
 * @Author: yd
 * @Date: 2020/7/18 10:17
 */
public class ListDemo {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("a");
        list.add("d");
        // foreach
        for (String str: list) {
            if ("a".equals(str)) {
                list.remove(str);
            }
        }

    }
}

Running will throw: java.util.ConcurrentModificationException The specific information of the exception is as follows:

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
	at java.util.ArrayList$Itr.next(ArrayList.java:859)
	at com.bootMybatis.demo.ListDemo.main(ListDemo.java:23)

Through source code analysis, we can see the exception thrown. When getting the next element, we will first check whether the two variables are equal. After the first remove, the value of modCount has changed from 5 to 6, so It causes the value to be different and throws an exception.

Two, ordinary for loop

package com.bootMybatis.demo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ListDemo {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("a");
        list.add("d");

        // 普通for循环
        for (int i = 0; i < list.size();i++){
            if (list.get(i).equals("a")){
                list.remove(list.get(i));
            }
        }

        for (String string:
             list) {
            System.out.println(string);
        }

    }
}

By deleting elements through this normal loop, you will find that there are multiple elements you want to delete, you can't delete them, because after deleting the elements, the array index changes, and the next element will not enter the comparison.

Third, the iterator uses the remove method of the list

package com.bootMybatis.demo;

import org.hibernate.validator.constraints.EAN;

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

/**
 * @Author: yd
 * @Date: 2020/7/18 10:17
 */
public class ListDemo {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("a");
        list.add("d");
        
        // 迭代器循环
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            String str = iterator.next();
            if ("a".equals(str)){
                list.remove(str);
            }
        }

    }
}

This method will throw the same exception as the enhanced for loop, and cause the same reason.

Fourth, the remove method of the iterator

package com.bootMybatis.demo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @Author: yd
 * @Date: 2020/7/18 10:17
 */
public class ListDemo {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("a");
        list.add("d");

        // 迭代器循环
        Iterator<String> iterator1 = list.iterator();
        while(iterator1.hasNext()){
            String str = iterator1.next();
            if ("a".equals(str)){
                iterator1.remove();
            }
        }

    }
}

This way can perfectly solve the problem of circular deletion.

Five, the for loop of JDK 1.8

package com.bootMybatis.demo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @Author: yd
 * @Date: 2020/7/18 10:17
 */
public class ListDemo {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("a");
        list.add("d");

        // JDK 1.8 的循环
        list.forEach(str -> {
            if ("a".equals(str)){
                list.remove(str);
            }
        });
        System.out.println(list.size());

    }
}

This method will also throw an exception: java.util.ConcurrentModificationException, we can find through the source code that it is still caused by the different values ​​of expectedModCount and modCount.

 

Guess you like

Origin blog.csdn.net/weixin_42228950/article/details/106670321