日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 对list增删_List 中正确的增删操作

發布時間:2025/3/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 对list增删_List 中正确的增删操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這個為什么要單獨說的原因是,在開發中的對數據庫中的增刪為最基本的,但是是不是寫對了就尤為重要

先來看代碼:

1 public voidtestLoopInList(){2 List a = new ArrayList();3 a.add("1");4 a.add("2");5 a.add("w");6 for(String string : a) {7 System.out.println(string);8 }9

10 for(String temp : a) {11 if("2".equals(temp)){12 a.remove(temp);13 }14 }15

16 for(String string : a) {17 System.out.println(string);18 }

輸出:

1

2java.util.ConcurrentModificationException

at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)

at java.util.ArrayList$Itr.next(ArrayList.java:831)

at test.Test_ForeachAndIterator.testLoopInList(Test_ForeachAndIterator.java:19)

出現錯誤了

原因:首先從錯誤中可以看出,是ArraList中的Iterator的checkForComodification()出現的錯誤,說明了foreach的實現原理其實就是實現了內部類I特Iterator來進行遍歷的,其次為什么會出錯呢?

因為在ArrayList和ArrayList的內部類的Iterator中的都會存在remove的方法,而ArrayList和Iterator中都各自有自己的維持長度的變量,前者是modCount,后者是expectModCount,但是源碼中ArrayList的remove方法是會改變modCount的值,但卻不會直接同步到expectModCount的值的,而Iterator中時刻都插入了checkForComodification()方法來監測modCount是否與expectModCount相等,所以就會很容易出現異常錯誤,當然下面的代碼也是錯的

1 public voidtestLoopInList(){2 List a = new ArrayList();3 a.add("1");4 a.add("2");5

6 for(String string : a) {7 System.out.println(string);8 }9

10 Iterator it =a.iterator();11 while(it.hasNext()){12 if("1".equals(it.next())){13 a.remove(it.next());14 }15 }16

17 for(String string : a) {18 System.out.println(string);19 }20 }

錯誤原因同上

所以在解決問題的關鍵就是要避免這個異常的出現,也就是時刻讓modCount==expectModCount,所以就是使用iterator的remove方法,因為會有使兩者相等的代碼

即下面:

1 public voidtestLoopInList(){2 List a = new ArrayList();3 a.add("1");4 a.add("2");5

6 for(String string : a) {7 System.out.println(string);8 }9

10 Iterator it =a.iterator();11 while(it.hasNext()){12 if("1".equals(it.next())){13 it.remove();14 }15 }16

17 for(String string : a) {18 System.out.println(string);19 }20 }

相關源碼提上:

1 private class Itr implements Iterator{2 /**

3 * Index of element to be returned by subsequent call to next.4 */

5 int cursor = 0;6 /**

7 * Index of element returned by most recent call to next or8 * previous. Reset to -1 if this element is deleted by a call9 * to remove.10 */

11 int lastRet = -1;12 /**

13 * The modCount value that the iterator believes that the backing14 * List should have. If this expectation is violated, the iterator15 * has detected concurrent modification.16 */

17 int expectedModCount =modCount;18 public booleanhasNext() {19 return cursor !=size();20 }21 publicE next() {22 checkForComodification();23 try{24 E next =get(cursor);25 lastRet = cursor++;26 returnnext;27 } catch(IndexOutOfBoundsException e) {28 checkForComodification();29 throw newNoSuchElementException();30 }31 }32 public voidremove() {33 if (lastRet == -1)34 throw newIllegalStateException();35 checkForComodification();36 try{37 AbstractList.this.remove(lastRet);38 if (lastRet

ArrayList中的remove

1 public booleanremove(Object o) {2 if (o == null) {3 for (int index = 0; index < size; index++)4 if (elementData[index] == null) {5 fastRemove(index);6 return true;7 }8 } else{9 for (int index = 0; index < size; index++)10 if(o.equals(elementData[index])) {11 fastRemove(index);12 return true;13 }14 }15 return false;16 }

當然你說我不用for增強,就用普通的for ,就不會有創建Iterator的操作,進而就不會有Iterator的實時監測維護值得操作,也行啊,但還是要注意有坑啊! 比如我們來看下面的代碼:

1 List list = newArrayList();2 Collections.addAll(list, 1, 2, 3, 4, 5);3 for(int i = 0; i < list.size(); ++i){4 int val = (int) list.get(i);5

6 //需求是刪除 3 和 4 兩個元素

7 if(3 == val || 4 ==val){8 list.remove(i);9 }10 }

這是我們非常常見的寫法,結果 為 :1 2 3 4

奇怪了,4為甚沒有刪除掉,其實仔細想想 還是能相同的 刪除了3之后 i = 3 size = 4,這時候,list.get返回值為5, 會跳過4

所以 修改的話,兩個 liter tips : 要么自己維護索引,要么反向循環

1 for(int i = list.size() - 1; i > 0; --i){2 int val = (int) list.get(i);3

4 //需求是刪除 3 和 4 兩個元素

5 if(3 == val || 4 ==val){6 list.remove(i);7 }8 }

1 for(int i = 0; i < list.size(); ++i){2 int val = (int) list.get(i);3

4 //需求是刪除 3 和 4 兩個元素

5 if(3 == val || 4 ==val){6 list.remove(i);7 i --; //刪除后,索引也應該變化

8 }9 }

ok, that's all ...

總結

以上是生活随笔為你收集整理的java 对list增删_List 中正确的增删操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。