Java基礎8:Iterator和foreach迴圈
一、Iterator簡介:
1、java.util.Iterator為一個介面,它只提供了迭代了基本規則,提供一種方法訪問某個容器(container)物件中的各個元素,而又不需暴露該物件的內部細節/底層結構。在 JDK 中他是這樣定義的:對collection 進行迭代的迭代器。從定義可見,Iterator(迭代器)模式又叫做Cursor(遊標)模式是為容器而生。它可以把訪問邏輯從不同型別的集合類中抽象出來,從而避免2、向客戶端暴露集合的內部結構。
2、迭代其實我們可以簡單地理解為遍歷,是遍歷各類容器裡面的所有物件的標準訪問方法,它是一個很典型的設計模式。很明顯,對容器物件的訪問必然涉及到遍歷演算法。你可以一股腦的將遍歷方法塞到容器物件中去;或者根本不去提供什麼遍歷演算法,讓使用容器的人自己去實現去吧。這兩種情況好像都能夠解決問題。
其原始碼如下:
- package java.util;
- publicinterface Iterator<E>
- {
- boolean hasNext();
- E next();
- void remove();
- }
二、Iterator用法
Java中的Iterator功能比較簡單,並且只能單向向前遍歷:
(1)容器呼叫iterator()要求集合類容器返回一個Iterator物件。注意:好多集合類都實現了java.lang.Iterable介面,這樣容器物件就可以呼叫iterator()方法。
(2)hasNext() 檢查容器中是否還有元素。
(3)next() 獲得容器中的下一個元素。第一次呼叫時,它返回容器的第一個元素。
(4)remove() 將迭代器新返回的元素刪除。
Iterator是Java迭代器最簡單的實現,為List設計的ListIterator具有更多的功能,它可以從兩個方向遍歷List,也可以從List中插入和刪除元素。List<String> strList = new ArrayList<>(); //1、using for-each loop for(String str : strList) System.out.println(str); //2、using iterator Iterator<String> it = strList.iterator(); while(it.hasNext()) { String str = it.next(); System.out.println(str); }
三、Fail-Fast(快速失敗)機制
我們知道的是ArrayList是執行緒不安全的,如果在使用迭代器的過程中有其他的執行緒修改了List就會丟擲ConcurrentModificationException這就是Fail-Fast機制,為了防止多執行緒下迭代的不安全操作。
那麼快速失敗究竟是個什麼意思呢?
在ArrayList類建立迭代器之後,除非通過迭代器自身remove或add對列表結構進行修改,否則在其他執行緒中以任何形式對列表進行修改,迭代器馬上會丟擲異常,快速失敗。
四、Iterator進階 1、列舉Enumeration 和Iterator介面之間的差異是什麼?列舉是快迭代兩倍,使用非常少的記憶體。列舉適合基本需求。但Iterator是更安全,因為它總是拒絕其他執行緒修改它正在迭代集合中的物件。
2、Iterator和listIterator之間有什麼不同?
我們可以使用迭代器Iterator遍歷Set和List集合,而ListIterator只可以使用List。
迭代器遍歷只有向前的方向,而ListIterator可以用來在兩個方向遍歷。
ListIterator繼承Iterator介面,並配備了額外的功能,如新增元素,更換一個元素,能獲得上一個和下一個元素的索引位置。
3.fail-fast與fail-safe有什麼區別?
Iterator的fail-fast屬性與當前的集合共同起作用,因此它不會受到集合中任何改動的影響。Java.util包中的所有集合類都被設計為fail-fast的,而java.util.concurrent中的集合類都為fail-safe的。當檢測到正在遍歷的集合的結構被改變時,Fail-fast迭代器丟擲ConcurrentModificationException,而fail-safe迭代器從不丟擲ConcurrentModificationException。
4、Iterator優點?①迭代器可以提供統一的迭代方式。
②迭代器也可以在對客戶端透明的情況下,提供各種不同的迭代方式。
③迭代器提供一種快速失敗機制,防止多執行緒下迭代的不安全操作。
五、foreach迴圈1 2 3 4 |
for (type
element:obj)
{
含有elemengt的 語句塊 //迴圈體
}
|
List<String> strList = new ArrayList<>();
strList.add("111");
strList.add("222");
strList.add("333");
for(String str : strList)
System.out.println(str);
2、適用範圍:對於任何實現Iterable介面的容器都可以使用foreach迴圈。foreach語法的冒號後面可以有兩種型別:一種是陣列,另一種是是實現了Iterable介面的類。
3、For-Each迴圈的缺點:丟掉了索引資訊。
當遍歷集合或陣列時,如果需要訪問集合或陣列的下標,那麼最好使用舊式的方式來實現迴圈或遍歷,而不要使用增強的for迴圈,因為它丟失了下標資訊。