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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

java list循环中删除元素的坑

發布時間:2025/3/21 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java list循环中删除元素的坑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

當我們要循環一個list中的元素,并且要刪除某個元素的時候,一點要小心謹慎!其中深埋了好幾個坑!

坑1

請看如下代碼:

/*** 測試刪除集合中的空白元素*/ @Test public void removeBlank() {List<String> list = new ArrayList<>();list.add("1");list.add("2");list.add("3");list.add(" ");list.add(" ");for (String s : list) {if (StringUtils.isBlank(s)) {list.remove(s);}}System.out.println("list:" + list); }

輸出結果:list:[1, 2, 3, ] 。可以看到空白元素沒有刪除干凈。

坑1解決辦法

請看如下代碼:

/*** 測試刪除集合中的空白元素*/ @Test public void removeBlank() {List<String> list = new ArrayList<>();list.add("1");list.add("2");list.add("3");list.add(" ");list.add(" ");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String s = iterator.next();if (StringUtils.isBlank(s)) {iterator.remove();}}System.out.println("list:" + list); }

結果輸出:list:[1, 2, 3]。解決辦法其實就是用Iterator迭代器代替for循環。但是這個解決方法里還是隱藏了一個坑。

坑2

請看如下代碼:

/*** 測試刪除集合中的空白元素*/ @Test public void removeBlank() {List<String> list = Arrays.asList("1","2","3",""," ");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String s = iterator.next();if (StringUtils.isBlank(s)) {iterator.remove();}}System.out.println("list:" + list); }

結果會直接報錯:java.lang.UnsupportedOperationException。意思是不支持remove操作。
只是把list的定義換成了Arrays.asList,卻有完全不一樣的運行結果,非常神奇。查看Arrays.asList的源碼:

/*** Returns a fixed-size list backed by the specified array. (Changes to* the returned list "write through" to the array.) This method acts* as bridge between array-based and collection-based APIs, in* combination with {@link Collection#toArray}. The returned list is* serializable and implements {@link RandomAccess}.** <p>This method also provides a convenient way to create a fixed-size* list initialized to contain several elements:* <pre>* List&lt;String&gt; stooges = Arrays.asList("Larry", "Moe", "Curly");* </pre>** @param <T> the class of the objects in the array* @param a the array by which the list will be backed* @return a list view of the specified array*/ @SafeVarargs @SuppressWarnings("varargs") public static <T> List<T> asList(T... a) {return new ArrayList<>(a); }

單從代碼看:return new ArrayList<>(a);應該是一個普通的ArrayList啊?!查看注釋:返回一個固定大小的list!也就是說add和remove操作肯定會報錯。同時也說明了這里的ArrayList不是我們平時使用的ArrayList。繼續跟蹤這個ArrayList:

/*** @serial include*/ private static class ArrayList<E> extends AbstractList<E>implements RandomAccess, java.io.Serializable {private static final long serialVersionUID = -2764017481108945198L;private final E[] a;ArrayList(E[] array) {a = Objects.requireNonNull(array);}... }

原來此處的ArrayList是Arrays的一個實現了AbstractList的內部類,并且沒有覆蓋add和remove方法,默認這2個方法是會直接報“UnsupportedOperationException”的。

坑2解決辦法

既然明白了報錯原因,解決辦法也很明顯了:

/*** 測試刪除集合中的空白元素*/ @Test public void removeBlank() {List<String> list = Arrays.asList("1","2","3",""," ");List<String> result= new ArrayList<>(list);Iterator<String> iterator = result.iterator();while (iterator.hasNext()) {String s = iterator.next();if (StringUtils.isBlank(s)) {iterator.remove();}}System.out.println("list:" + result); }

反思

通過踩這幾個坑,再次驗證了一個真理:在設計一個對外方法的時候,一點要謹慎處理集合和數組。因為你永遠不知道客戶端傳給你的集合是什么,也不知道客戶端是否會有對此集合有任何其他的不可控的操作。所以在使用客戶端傳遞的集合對象時,最好拷貝一個新集合后再操作。

更新-2016.01.17

之前的解決方法中違反了java其中的一個編碼準則:變量的作用范圍越小約好。

請看如下代碼:

@Test public void testForAndWhile() {List<String> names1 = Lists.newArrayList("張三", "李四");Iterator<String> iterator1= names1.iterator();while (iterator1.hasNext()) {String name = iterator1.next();System.out.println("name1:" + name);iterator1.remove();}List<String> names2 = Lists.newArrayList("趙六", "錢七");Iterator<String> iterator2= names2.iterator();while (iterator1.hasNext()) {String name = iterator2.next();System.out.println("name2:" + name);iterator2.remove();} }

這段代碼的第二個循環不會打印任何東西,因為while條件中誤用了第一個循環中的變量,造成的bug。但是這種bug卻不會有任何編譯錯誤和運行時錯誤,危害甚大。但是只要改成舊版for循環的形式,就可以很好的避免這種錯誤。

請看如下改進代碼:

@Test public void testForAndWhile() {List<String> names1 = Lists.newArrayList("張三", "李四");for (Iterator<String> iterator= names1.iterator();iterator.hasNext();) {System.out.println("name1:"+iterator.next());iterator.remove();}List<String> names2 = Lists.newArrayList("趙六", "錢七");for (Iterator<String> iterator= names2.iterator();iterator.hasNext();) {System.out.println("name2:"+iterator.next());iterator.remove();} }

這個時候,如果錯誤的引用循環1中的代碼,會有編譯時錯誤,就可以很好的避免這種問題


from:?https://zacard.net/2016/01/07/list-remove/

總結

以上是生活随笔為你收集整理的java list循环中删除元素的坑的全部內容,希望文章能夠幫你解決所遇到的問題。

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