之前在使用list集合循環刪除元素的時候,竟然出現了集合內的元素不能刪除成功的問題,之后整理了一下,發現大有玄機!
1.如果指定了list的size大小,會出現下標越界異常
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
System.out.println("刪除前的list:"+list.toString());
for (int i = 0,len=list.size(); i < len; i++) {
if("c".equals(list.get(i))){
list.remove(i);
}
}
System.out.println("刪除后的list"+list.toString());
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
因為當刪除元素c的時候,list集合大小改變了
2.如果每次都動態的獲取list的size,當刪除多個元素的時候會出現后面元素刪除不成功的問題。
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
System.out.println("刪除前的list:"+list.toString());
for (int i = 0; i < list.size(); i++) {
if("c".equals(list.get(i))||"d".equals(list.get(i))){
list.remove(i);
}
}
System.out.println("刪除后的list"+list.toString());
刪除前的list:[a, b, c, d, e, f]
刪除后的list[a, b, d, e, f]
經過分析:當list刪除元素c的時候,此時的i=2,后面的元素會向前補一位,進行下一次循環的時候,此時list集合中的元素為[a, b, d, e, f],i=3,這樣會跳過d,從而導致d元素不能刪除成功。
3.增強for循環方式刪除元素,java.util.ConcurrentModificationException
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
System.out.println("刪除前的list:"+list.toString());
for (String s : list) {
if("c".equals(s)){
list.remove(s);
}
}
System.out.println("刪除后的list"+list.toString());
Exception in thread "main" java.util.ConcurrentModificationException
刪除前的list:[a, b, c, d, e, f]
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at operation.ListRemove.main(ListRemove.java:23)
從錯誤中可以定位到checkForComodification(ArrayList.java:901)
當modCount和expectedModeCount不相等時就會拋出此異常。
modCount是ArrayList類中的一個成員變量,表示對ArrayList的修改次數
expectedModCount:表示對ArrayList修改次數的期望值,它的初始值為modCount
當循環遍歷的時候二者是相等的,但是當執行list.remove()方法后,
可以看到modCount++,元素前移,最后一位置空,但是expectedModCount並沒有改變。
這就導致modCount和expectedModCount的值不一致。
刪除完再次遍歷的時候,
此時就會拋出異常了。
4.正確的刪除方式
難道就不能刪除了嗎???這是不可能的,正確的姿勢是什么呢?那就是迭代器--Iterator了
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
System.out.println("刪除前的list:"+list.toString());
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if("c".equals(next)){
iterator.remove();
}
}
System.out.println("刪除后的list"+list.toString());
刪除前的list:[a, b, c, d, e, f]
刪除后的list[a, b, d, e, f]
binggo~~~~~~~~~~~完美解決
其實:如果只是刪除某一個元素,上面的方法都可以。
如果是循環刪除多個,還是用迭代器吧!
不足之處歡迎指正!