一、常見誤區
1、提前結束遍歷(直接使用列表長度進行遍歷)
for(int i = 0;i < list.size();i++){ list.remove(i); }
在list不斷地刪除元素的同時,總列表list的長度也在不斷縮小,i值會提前和列表的總長度相等,導致遍歷提前結束,造成前面的元素刪掉了,但是結束時的長度後面的元素未能刪掉。
2、下標越界(提前固定列表長度進行遍歷)
int len = list.size(); for(int i = 0;i < len;i++){ list.remove(i); }
相比於上一種提前結束的,這種方式提前取出了原列表的總長度,避免了遍歷刪除時長度變化導致提前結束。但依舊無法避免列表的動態變化,列表隨着刪除元素在不斷縮小,後續的長度比原列表小的多,在遍歷到超出現有列表的長度時,就會出現下標越界的問題。
二、可用方式
測試數據(遍歷刪除以下列表中包含“產品”的):
List<String> deptList = Arrays.asList("產品研發部","產品交付部","系統運維部","系統安全部","市場運營部","人事管理部");
注:Arrays.asList生成的列表爲定長列表,僅用來展示,不可進行add、remove等操作,需要後續轉化爲arraylist進行相關操作。
1、反向遍歷(正向遍歷刪除會導致列表長度的縮小,與索引的逐漸增大現象結合後就會出現相應問題,只要反向使長度縮小和索引同步縮小結合就能避免)
List<String> newList = new ArrayList<>(deptList); for(int i = newList.size() - 1; i > -1; i--){ if(newList.get(i).indexOf("產品") != -1){ newList.remove(i); } }
2、迭代器遍歷(迭代器類似於鏈表形式吧,過完一個元素就到下一個,不會像索引和長度兩者結合使用一樣出現跳過或者越界的情況)
List<String> newList = new ArrayList<>(deptList); for(Iterator<String> iterator = newList.iterator(); iterator.hasNext(); ){ if(iterator.next().indexOf("產品") != -1){ iterator.remove(); } }
三、另闢蹊徑
刪除操作其實可以用篩選來代替,直接篩選出來有用的部分數據,就相當於遍歷刪除了無用的數據。
通過列表的流篩選操作進行處理過濾:
List<String> newList = new ArrayList<>(deptList); List<String> resultList = newList.stream().filter(item -> item.indexOf("產品") == -1).collect(Collectors.toList());
最後效果是一樣的,怎麼方便怎麼來。