本文已参与「新人创作礼」活动,一起开启掘金创作之路。
最近写Java代码使用for循环遍历集合并在其中删除满足条件的元素时,发现集合明明有5个元素,遍历却不足5次,经过排查后发现是自己犯了一个不该犯的错误,就是在for循环中删除了一个元素后,下次遍历的集合size已经-1了,而用来遍历计数的变量i在上次的循环中已经+1,从而导致循环次数不足集合的原始长度。
问题重现例子,删除集合里的3:
public class CollectionTest {
public static void main(String[] args) {
Integer[] intArray = new Integer[]{1, 2, 3, 3, 4, 5, 6, 7, 8, 9};
List<Integer> intList = new ArrayList<Integer>(Arrays.asList(intArray));
System.out.println("删除前:"+intList);
System.out.println("size:"+intList.size());
for (int i = 0; i < intList.size(); i++){
if (intList.get(i) == 3){
intList.remove(i);
}
}
System.out.println("删除后:"+intList);
System.out.println("size:"+intList.size());
}
}
运行结果:
删除前:[1, 2, 3, 3, 4, 5, 6, 7, 8, 9]
size:10
删除后:[1, 2, 3, 4, 5, 6, 7, 8, 9]
size:9
可以看到,这样写并没有达到开始的目的,集合中仍有3。
解决这个问题最简单的方法就是在删除元素之后将变量i--,这样就和前面的i++抵消了,下次循环不会跳过第2个3,从而删除满足条件的元素:
public class CollectionTest {
public static void main(String[] args) {
Integer[] intArray = new Integer[]{1, 2, 3, 3, 4, 5, 6, 7, 8, 9};
List<Integer> intList = new ArrayList<Integer>(Arrays.asList(intArray));
System.out.println("删除前:"+intList);
System.out.println("size:"+intList.size());
for (int i = 0; i < intList.size(); i++){
if (intList.get(i) == 3){
intList.remove(i);
i--;
}
}
System.out.println("删除后:"+intList);
System.out.println("size:"+intList.size());
}
}
运行结果:
删除前:[1, 2, 3, 3, 4, 5, 6, 7, 8, 9]
size:10
删除后:[1, 2, 4, 5, 6, 7, 8, 9]
size:8
除了这个方法以外,还可以通过迭代器来实现:
public class CollectionTest {
public static void main(String[] args) {
Integer[] intArray = new Integer[]{1, 2, 3, 3, 4, 5, 6, 7, 8, 9};
List<Integer> intList = new ArrayList<Integer>(Arrays.asList(intArray));
System.out.println("删除前:"+intList);
System.out.println("size:"+intList.size());
Iterator<Integer> it = intList.iterator();
while(it.hasNext()){
if (it.next() == 3){
it.remove();
}
}
System.out.println("删除后:"+intList);
System.out.println("size:"+intList.size());
}
}
运行结果:
删除前:[1, 2, 3, 3, 4, 5, 6, 7, 8, 9]
size:10
删除后:[1, 2, 4, 5, 6, 7, 8, 9]
size:8