1、想象出来的题目
假设有如下数组,现在要求在一个循环内将内容为C开头的都删掉
2、错误的写法
package com.demo;
import java.util.ArrayList;
import java.util.List;
public class ListRemoveDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>(5);
list.add("A");
list.add("B");
list.add("C1");
list.add("C2");
list.add("D");
list.add("E");
System.out.println("删除前的list:" + list.toString());
for (int i = 0; i < list.size(); i++) {
String str = list.get(i);
if (str.startsWith("C")) {
list.remove(i);
}
}
System.out.println("删除后的list:" + list.toString());
}
}
出问题的原因:
在删除C1后,C2向前进一位,原本的下标位置3变成了2。此时继续循环 i 指向到了下标3,也就是内容为D的值,因此肯定删除不了C2
3、正确的写法
3.1、倒叙删除法
package com.demo;
import java.util.ArrayList;
import java.util.List;
public class ListRemoveDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>(5);
list.add("A");
list.add("B");
list.add("C1");
list.add("C2");
list.add("D");
list.add("E");
System.out.println("删除前的list:" + list.toString());
//注意i的初始值一定为list.size() - 1, 因为这才是数组中的最后一个数据
//判断条件一定是i>=0,不能是i>0, 因为i = 0 也要参与逻辑的运算
for (int i = list.size() - 1; i >= 0; i--) {
String str = list.get(i);
if (str.startsWith("C")) {
list.remove(i);
}
}
System.out.println("删除后的list:" + list.toString());
}
}
从后向前删,解决了下标混乱的问题,所以可以成功
3.2、使用迭代器删除(iterator)(推荐)
package com.demo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListRemoveDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>(5);
list.add("A");
list.add("B");
list.add("C1");
list.add("C2");
list.add("D");
list.add("E");
System.out.println("删除前的list:" + list.toString());
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String str = iterator.next();
if (str.startsWith("C")) {
iterator.remove();
}
}
System.out.println("删除后的list:" + list.toString());
}
}
Iterator.remove() 方法会在删除当前迭代对象的同时,会保留原来元素的索引。