020_List遍历删除的方式

2020-11-01   65 次阅读


1.1 foreach循环

直接foreach循环删除会抛java.util.ConcurrentModificationException异常

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    for (String platform : platformList) {
        if (platform.equals("博客园")) {
            platformList.remove(platform);
        }
    }

    System.out.println(platformList);
}

foreach循环在实际执行时,其实使用的是Iterator,使用的核心方法是hasnext()和next()。
image.png
每次调用next()时都会比较modCount和expectedModCount的值
image.png
而list的remove()方法会增加modCount的值,所以下一次调用next()时会抛异常。

1.2 Iterator循环

使用Iterator的remove()方法

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    Iterator<String> iterator = platformList.iterator();
    while (iterator.hasNext()) {
        String platform = iterator.next();
        if (platform.equals("博客园")) {
            iterator.remove();
        }
    }

    System.out.println(platformList);
}

image.png
每次删除一个元素,都会将modCount的值重新赋值给expectedModCount,这样2个变量就相等了,不会触发java.util.ConcurrentModificationException异常。

1.3 For循环正序

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    for (int i = 0; i < platformList.size(); i++) {
        String item = platformList.get(i);

        if (item.equals("博客园")) {
            platformList.remove(i);
			//重点,删除元素后,要修正下下标的值:
            i = i - 1;
        }
    }

    System.out.println(platformList);
}

1.4 For循环倒序

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    for (int i = platformList.size() - 1; i >= 0; i--) {
        String item = platformList.get(i);

        if (item.equals("掘金")) {
            platformList.remove(i);
        }
    }

    System.out.println(platformList);
}

和使用for循环正序遍历类似,不过不用再修正下标

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议