Iterator-Java

在Java中,Iterator的做用就是爲了方便處理集合中的元素。例如獲取和刪除集合中的元素。java

在JDK8,Iterator接口提供了以下方法:安全

迭代器Iterator最基本的兩個方法是next()和hasNext()。其中Java迭代器多了一個remove()方法。在JDK8中又新增了forEachRemaining()方法。併發

接下來,以ArrayList爲例,看下迭代器在Java中的實現。ui

在ArrayList中,之內部類的方式實現,每次調用iterator()方法,都會new Itr()。this

先看一下ArrayList迭代器的實現類:spa

定義的參數以下:3d

1 int cursor;       // 下標,默認值0;
2 int lastRet = -1; //最後一個元素的下標,若是沒有返回-1;
3 int expectedModCount = modCount;//結構修改(添加、刪除等操做)次數,默認值0;

定義的方法以下:code

hasNext()方法: 
對象

1  public boolean hasNext() {
2      return cursor != size;
3 }

當集合中不存在下一個元素,即已經遍歷至集合末尾時,該方法返回false。hasNext 方法主要用於循環終止條件。blog

next()方法:

 1 public E next() {
 2     checkForComodification();
 3     int i = cursor;
 4     if (i >= size)
 5         throw new NoSuchElementException();
 6     Object[] elementData = ArrayList.this.elementData;
 7     if (i >= elementData.length)
 8         throw new ConcurrentModificationException();
 9     cursor = i + 1;
10     return (E) elementData[lastRet = i];
11 }

在執行next()方法時,會先執行checkForComodification()方法,作一個判斷(檢查所迭代的列表對象是否被修改過):

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

在對集合進行迭代過程當中,不容許出現迭代器之外的對元素的操做,由於這樣會產生安全隱患,java會拋出異常併發修改異常(ConcurrentModificationException),普通迭代器只支持在迭代過程當中的刪除動做。

若是在遍歷ArrayList時,想添加元素和修改元素,能夠調用List集合的特有迭代器ListIterator。

remove()方法:

 1 public void remove() {
 2     if (lastRet < 0) throw new IllegalStateException();
 3     checkForComodification();
 4 
 5     try {
 6         ArrayList.this.remove(lastRet);
 7         cursor = lastRet;
 8         lastRet = -1;
 9         expectedModCount = modCount;
10     } catch (IndexOutOfBoundsException ex) {
11         throw new ConcurrentModificationException();
12     }
13 }

Java普通迭代器中惟一支持修改結構的操做。在執行完刪除操做後,會更新expectedModCount字段的值。

forEachRemaining()方法:

 1 public void forEachRemaining(Consumer<? super E> consumer) {
 2     Objects.requireNonNull(consumer);
 3     final int size = ArrayList.this.size;
 4     int i = cursor;
 5     if (i >= size) {
 6         return;
 7     }
 8     final Object[] elementData = ArrayList.this.elementData;
 9     if (i >= elementData.length) {
10         throw new ConcurrentModificationException();
11     }
12     while (i != size && modCount == expectedModCount) {
13         consumer.accept((E) elementData[i++]);
14     }
15     // update once at end of iteration to reduce heap write traffic
16     cursor = i;
17     lastRet = i - 1;
18     checkForComodification();
19 }

forEachRemaining()是JDK8中新增的方法。forEachRemaining()使用迭代器Iterator的全部元素,而且第二次調用它將不會作任何事情,由於再也不有下一個元素。

一個使用場景:得到對應集合的迭代器Iterator,而後您能夠開始迭代,next()直到達到某個條件,而後使用forEachRemaining()操做該Iterator上的其他部分。

接下來,看一下剛纔提到的ListIterator。

在普通的Iterator中,只能對元素進行獲取(next())和刪除(remove())的操做。而ListIterator提供了更多的方法:

add(E e): 將指定的元素插入列表,插入位置爲迭代器當前位置以前
hasNext():以正向遍歷列表時,若是列表迭代器後面還有元素,則返回 true,不然返回false
hasPrevious():若是以逆向遍歷列表,列表迭代器前面還有元素,則返回 true,不然返回false
next():返回列表中ListIterator指向位置後面的元素
nextIndex():返回列表中ListIterator所需位置後面元素的索引
previous():返回列表中ListIterator指向位置前面的元素
previousIndex():返回列表中ListIterator所需位置前面元素的索引

在使用特有的迭代器時,咱們就能作更多的操做了。

相關文章
相關標籤/搜索