Java中Iterator(迭代器)與foreach學習


1.迭代器使用

Iterator(迭代器)給我們提供了一種遍歷序列的方式,其中主要關於以下幾種方法:

1.iterator()方法,返回一個Iterator對象。

2.next()方法,獲取迭代器的下一個元素,並會向后移動一個單位(注:初次調用next()會返回序列中的第一個元素)

3.hasNext()方法,判斷迭代器是否還有下一個元素(不會移動迭代器)

4.remover()方法,刪除當前的迭代器所指向元素,一般與next()方法連用

 

Iterator遍歷序列實施操作示例:

Iterator iter  = subjects.iterator();//subjects為字符串序列
while(iter.hasNext()){
       subject = iter.next();
       if(subject.startsWith("6.")){//將以6.開頭的字符串從序列中移除
           iter.remove();
       }
}    

 

foreach語句格式:

  for(元素類型type  元素變量value : 遍歷對象obj) { 

    引用value的語句;  

}

2.foreach過程分析

foreach內部調由迭代器實現,但是當需要刪除序列元素時,foreach循環會發生錯誤

如:

分析:

ConcurrentModificationException異常

Iterator next方法實現源碼:

public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
        throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
}

final void checkForComodification() {
    if (modCount != expectedModCount)
       throw new ConcurrentModificationException();
}

在next方法中首先調用了checkForComodification方法,該方法會判斷modCount是否等於expectedModCount,不等於就會拋出java.util.ConcurrentModificationExcepiton異常。

注:modCount是ArrayList的一個屬性,繼承自抽象類AbstractList,用於表示ArrayList對象被修改次數(add、remove、clear、ensureCapacityInternal均會改變modCount值)。在創建Iterator的時候會將modCount賦值給expectedModCount,之后expectedModCount不再改變。設置該檢查的目的是為了阻止程序員在不允許修改的時候修改對象,Iterator 被創建之后會建立一個指向原來對象的單鏈索引表,當原來的對象數量發生變化時,這個索引表的內容不會同步改變。 當索引指針往后移動的時候就找不到要迭代的對象,所以禁止迭代時修改對象,於是會拋出錯誤。

在執行next方法時,將會檢查modCount與expectedModCount值,由於foreach方法中,其內部由iterator實現,也會調用next()方法,但是,每次刪除元素時均會改變modCount值,因此,調用序列自身的remove()方法后再次調用next()方法時,經檢查modCount != expectedModCount,因此拋出ConcurrentModificationException異常

  然而,在使用迭代器時,對迭代中的元素進行刪除並不會拋出錯誤,原因是:在iterator.remove()方法中,同樣調用了ArrayList自身的remove方法,但是調用完之后並非就return了,而是expectedModCount = modCount重置了expectedModCount值,使二者的值繼續保持相等。同時,Iterator.remove() 方法會在刪除當前迭代對象的同時維護索引的一致性,不會導致索引指針移動時找不到迭代對象。

下面使用迭代器的語句同樣會拋出ConcurrentModificationException異常:

 

Iterator iter  = subjects.iterator();
while(iter.hasNext()){
       subject = iter.next();
       if(subject.startsWith("6.")){
           subjects.remove(subject);//僅將iter.remove()更改為subjects.remove(subject)
       }
}    

 

可以看出,異常確實是由迭代器在迭代過程中拋出

 

 

參考:

1.Java中Iterator用法整理

2.java.util.ConcurrentModificationException 異常問題詳解

3.ConcurrentModificationException迭代集合刪除元素!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM