ArrayList中漏删的情况
问题描述
需求描述:
现需要将ArrayList中存放的所有以“陈”开头的元素删除
原始ArrayList:
list = [陈奕迅, 陈嘉桦, 陈粒, 五月天, 苏打绿, Oasis, 王菲]
目标ArrayList:
list = [五月天, 苏打绿, Oasis, 王菲]
最快能想到的做法:
1.遍历list(不能使用增强for以及Iterator,因为会对集合中的元素进行增删改操作,使用了便会报ConcurrentModificationException:并发修改异常),取元素
2.判断该元素是否以“陈”开头的元素
是:删除
否:不进行操作
相应代码:
for (int i = 0; i < list.size(); i++) {
String name = list.get(i);
if (name.startsWith("陈")){
list.remove(i);
}
}
但是打印输出,发现实际上的结果:list = [陈嘉桦, 五月天, 苏打绿, Oasis, 王菲],出现了漏删的情况
原因分析
产生漏删的原因:
1.i=0, "陈奕迅".startsWith("陈"),remove("陈奕迅")
2.原来索引为1的"陈嘉桦"此时索引会变为0,原来索引为2的"陈粒"此时索引会变为1...(删除元素之后的所有元素索引在原有索引的基础上都减去1)
而此时i=1,因此就跳过了对"陈嘉桦"的判断,也就没有删除"陈嘉桦",删除了"陈粒"
解决办法
解决办法1:
仍然使用正序遍历的前提下,在if方法体内加一个i--,使其不会漏掉索引为0的元素的姓名开头的判断
for (int i = 0; i < list.size(); i++) {
String name = list.get(i);
if (name.startsWith("陈")){
list.remove(i);
i--;
}
}
System.out.println("list = " + list);
解决办法2:
倒序遍历(因为倒序遍历,修改索引的部分是已经判断过的元素,所以不会出现漏删的情况)
for (int i = list.size() - 1; i >= 0; i--) {
String name = list.get(i);
if (name.startsWith("陈")){
list.remove(i);
}
}
System.out.println("list = " + list);
代码实现
package com.tan.arraylist;
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("陈奕迅");
list.add("陈嘉桦");
list.add("陈粒");
list.add("五月天");
list.add("苏打绿");
list.add("Oasis");
list.add("王菲");
System.out.println("list = " + list);
for (int i = 0; i < list.size(); i++) {
String name = list.get(i);
if (name.startsWith("陈")){
list.remove(i);
}
}
System.out.println("list = " + list);
for (int i = 0; i < list.size(); i++) {
String name = list.get(i);
if (name.startsWith("陈")){
list.remove(i);
i--;
}
}
System.out.println("list = " + list);
for (int i = list.size() - 1; i >= 0; i--) {
String name = list.get(i);
if (name.startsWith("陈")){
list.remove(i);
}
}
System.out.println("list = " + list);
}
}