java中ArrayList使用remove刪除元素時幾種常見的問題及解決辦法
一,for迴圈使用remove()刪除座標來刪除元素。
問題現象:迴圈的時候被刪除元素的下個元素不能讀取到。程式碼現象如下:
List<String> testList1 = new ArrayList<String>();//全部元素集合 test0……test6
for (int i = 0; i < 6; i++) {
testList1.add("test"+i);
}
List<String> testList2 = new ArrayList<String>();//部分元素集合 test2 test3 test4 test5
for (int i = 2; i < 6; i++) {
testList2.add("test"+i);
}
//現在要刪除testList1 中包含testList2中的元素
System.out.println("testList1原集合元素:");
for (int i = 0; i < testList1.size(); i++) {
System.out.println(" "+testList1.get(i));
}
for (int i = 0; i < testList1.size(); i++) {
if(testList2.contains(testList1.get(i))){
testList1.remove(i);
}
}
System.out.println("testList1刪除testList2中的元素後:");
for (int i = 0; i < testList1.size(); i++) {
System.out.println(" " +testList1.get(i));
}
結果如下:
testList1原集合元素:
test0
test1
test2
test3
test4
test5
testList1刪除testList2中的元素後:
test0
test1
test3
test5
testList1 中test3和test5元素未被刪除。是test2這個物件被刪除了,test2後邊的元素對應的向前移動一位,對應的索引index也減1,因此在刪除test2時對應的的i=2,刪除之後i++,而test3對應的索引變成了由3變成2,所以實際上test3沒有讀取到,對應的test5一樣道理。
解決辦法,只需要在testList1.remove(i);之後加i–即可。讓元素刪除之後index回到刪除之前的大小。
假如您不是按順序每次讀取一個元素而是隔n個讀,還是加個i–即可,因為移除一個元素其index總是減一。 二,三種迭代刪除會出現以下異常:
JException in thread “main” java.util.ConcurrentModificationException
at java.util.AbstractList
三種情況如下:
Iterator it = testList1 .iterator();
while (it.hasNext()) {
String value = (String) it.next();
if (testList2.contains(value)) {
testList1 .remove(value);
}
}
for (Iterator it2 = testList1 .iterator(); it2.hasNext();) {
String value = (String) it2.next();
if (testList2.contains(value)) {
testList1 .remove(value);
}
}
for (String value : testList1 ) {
if (testList2.contains(value)) {
testList1 .remove(value);
}
}
這種情況是因為導致List的next()方法內部出現modCount和expectedModCount不一致導致丟擲異常。,可直接修改util包中的原始碼解決這類問題,或者直接採用iterator.remove();解決問題
for (Iterator it = myList.iterator(); it.hasNext();) {
String value = it.next();
if (value.equals( "3")) {
it.remove();
}
}