文章目錄
1. 集合遍歷
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);
arr.add(3);
arr.add(5);
arr.add(7);
arr.add(9);
arr.add(10);
for(int i=0;i<arr.size();i++) {
System.out.print(arr.get(i)+" ");
}
System.out.println();
for(int i:arr) {
System.out.print(i+" ");
//arr.remove(i);可編譯通過,但是運行時報異常java.util.ConcurrentModificationException 併發修改異常
}
System.out.println();
Iterator<Integer> lt= arr.iterator();
while(lt.hasNext()) {
System.out.print(lt.next()+" ");
//從集合中刪除上一次next()方法返回的元素
lt.remove();
}
}
1.1 普通for循環遍歷
優點:效率最高,遍歷快,可以根據計數器(下標)操作元素
缺點:不適用所有集合,適用範圍小,不適用於Map、Set
1.2 foreach循環(增強for循環)遍歷
可以看出,使用foreach循環遍歷元素時無須獲得數組長度,也無須根據索引來訪問數據。foreach循環和普通for循環不同的是,它無須循環條件,無須循環迭代語句。
注:使用foreach循環遍歷數組元素時,並不能改變數組元素的值,會報異常java.util.ConcurrentModificationException
(併發修改異常)
優點:代碼簡潔,不易出錯。
缺點:只能做簡單的遍歷,不能在遍歷過程中刪除、替換數據。
1.3 Iterator迭代器遍歷
Inerator接口只能用於遍歷Collection集合中的元素,Iterator對象也被稱爲迭代器。Iterator接口裏提供的方法:
boolean hasNext()
:如果被迭代的集合元素還沒有遍歷完,則返回trueObject next()
:返回集合裏的下一個元素void remove()
:刪除集合中上一次next()方法返回的元素void forEachRemaining(Consumer action)
:Java 8爲Iterator新增的默認方法,此方法可使用Lambda表達式遍歷集合元素
Iterator<Integer> lt= arr.iterator();
while(lt.hasNext()) {
int temp = lt.next();
System.out.print(temp+" ");
}
- Iterator依賴於Collection對象,Iterator對象提供了
hasNext()
和next()
兩個方法來迭代訪問Collection集合裏的對象。 - 只有通過
Iterator的remove()
方法才能刪除上一次next()方法返回的集合元素,使用list的remove()方法將會引發java.util.ConcurrentModificationException
(併發修改異常)
2. 集合刪除
集合的刪除只有兩種方式:
2.1 使用普通for循環刪除
此處省略代碼。。。
2.2 Iterator遍歷時調用Iterator的remove()方法,而不是list的remove()方法進行刪除
Iterator<Integer> lt= arr.iterator();
while(lt.hasNext()) {
int temp = lt.next();
System.out.print(temp+" ");
//arr.remove(temp);報異常java.util.ConcurrentModificationException 併發修改異常
lt.remove();//從集合中刪除上一次next()方法返回的元素,刪除成功
}
- Iterator迭代器採用的是快速失敗(fail-fast)機制,一旦在迭代過程中檢測到該集合已被修改,程序會立刻報出
ConcurrentModificationException
(併發修改異常),而不是顯示修改後的結果,這樣可以避免共享資源而引發的線程非安全問題。 - 只有通過
Iterator的remove()
方法才能刪除上一次next()方法返回的集合元素,使用list的remove()方法將會引發java.util.ConcurrentModificationException
(併發修改異常)
爲什麼不能用foreach遍歷刪除List中的元素呢?
foreach底層實現還是調用的Iterator迭代器,但是在進行remove操作時,使用的是list的remove方法,而非Iterator的remove方法,那麼,在我們調用list的remove方法刪除元素之後,迭代器並不知道我們刪除了這個元素,所以遍歷時報錯。
具體原因看源碼:Java中的 fail-fast