最近整理笔记时,发现有几个有意思的常犯错误,在此分享下。
问题:如何批量删除List中的元素呢?
比如:List大小为100,只删除前50个,怎么办?
List<Integer> list = new ArrayList<Integer>(Arrays.asList(10,20,30,40,50,60,70,80));
for (int i = 0; i < list.size(); i++) {
list.remove(i);
System.out.println("当前值:"+list.get(i)+",执行次数"+i);
}
执行结果:仅删除了list长度值一半的数据
当前值:20,执行次数0
当前值:40,执行次数1
当前值:60,执行次数2
当前值:80,执行次数3
原因:
因为在remove时,List的大小(size)就会缩减,同时也改变了索引的指向,所以无法全部批量删除。
List<Integer> list = new ArrayList<Integer>(Arrays.asList(10,20,30,40,50,60,70,80));
int m = 1;
for (Integer obj : list) {
list.remove(obj);
System.out.println("当前值:" + obj + ",执行次数" + m++);
}
执行结果:抛异常
当前值:10,执行次数1
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
原因:
在 foreach循环中,编译器使得 remove()方法先于next()方法被调用,这就导致了ConcurrentModificationException 异常。所以抛异常。
int i = 0;
List<Integer> list = new ArrayList<Integer>(Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80));
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer num = iterator.next();//必须在remove()之前,显式调用next()
iterator.remove();
System.out.println("当前值:" + num + ",执行次数" + ++i);
}
执行结果:全部成功删除
当前值:10,执行次数1
当前值:20,执行次数2
当前值:30,执行次数3
当前值:40,执行次数4
当前值:50,执行次数5
当前值:60,执行次数6
当前值:70,执行次数7
当前值:80,执行次数8
注意:
iterator.next()
必须在iterator.remove()
之前显式调用。 iterator.remove()
,再调用iterator.next()
,抛出以下异常:Exception in thread "main" java.lang.IllegalStateException
at java.util.ArrayList$Itr.remove(ArrayList.java:864)
at com.darwin.junit.Calculator.main(Calculator.java:69)