集合遍歷(三種)與刪除(兩種)

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():如果被迭代的集合元素還沒有遍歷完,則返回true
  • Object 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章