Java Iterator ListIterator 理解

1、 Iterator 經常使用操做 next hasNext remove  java

先上源碼:JDK8 簡化版本,用於說明問題c++

 1 private class Itr implements Iterator<E> {  2     int cursor;       // index of next element to return
 3     int lastRet = -1; // index of last element returned; -1 if no such
 4 
 5     public boolean hasNext() {  6         return cursor != size;  7  }  8     
 9     public E next() { 10         int i = cursor; 11         Object[] elementData = ArrayList.this.elementData; 12         cursor = i + 1; 13         return (E) elementData[lastRet = i]; 14  } 15 
16     public void remove() { 17         ArrayList.this.remove(lastRet); 18         cursor = lastRet; 19         lastRet = -1; 20  } 21     
22 }

約定: Iterator  it = xxx.iterator(); 數組

疑惑1: 爲何不像 c++ 中 iterator 直接 *it 就能夠獲取當前值,java必需要 Object obj = it.next();函數

答:查看源碼發現 調用 next 函數有兩個做用,一個是獲取當前 cusor 指向位置的元素,另外一個是指針cusor 後移,而且 賦值 lastRet 變量(這裏很關鍵)this

疑惑二:爲何數組的最後一個元素進行 hasNext 返回真?spa

答:在迭代器中 可訪問範圍爲 [0, size] 不是 [0, size)。所以傳統意義數組的最後一個元素的下一個是 array[size], 儘管這個是無心義的,可是在迭代器中算一個特殊迭代器(相似 C++ . iterator.end() )指針

疑惑三:爲何刪除元素不能夠這麼寫?code

1 while(it.hasNext()){ 2   it.remove(); 3   it.next(); 4 }

答:查看疑問一答中,next函數會賦值變量 lastRet ,這個變量對於 remove 函數至關重要。 所以在首次進入 while 循環的時候, laseRet = -1 (默認狀態),所以不能直接進行 remove ,數組越界。blog

因此正確的應該是索引

1 while(it.hasNext()){ 2  it.next(); 3  it.remove(); 4 }

 

2、 ListIterator 中 lastIndex previousIndex previous

先上源碼:JDK8 簡化版本,用於說明問題

 1      public boolean hasPrevious() {  2             return cursor != 0;  3  }  4 
 5         public int nextIndex() {  6             return cursor;  7  }  8 
 9         public int previousIndex() { 10             return cursor - 1; 11  } 12 
13         public E previous() { 14             int i = cursor - 1; 15             Object[] elementData = ArrayList.this.elementData; 16             cursor = i; 17             return (E) elementData[lastRet = i]; 18         }

疑惑一: 如何獲取正確的 前一個元素的下標值和後一個元素的下標值?

答:先看一段代碼:

1 public static void main(String[] args) { 2     List<Integer> list = new ArrayList<Integer>(Arrays.asList(4, 5, 6, 7, 8)); 3     ListIterator<Integer> it = list.listIterator(); 4  System.out.println(it.previousIndex()); 5  System.out.println(it.nextIndex()); 6 }
//output
-1
0

顯然輸出並不正確,咱們指望獲得的是 -1 1

解釋這個現象看源碼,咱們發現 

① previousIndex 和 nextIndex 只能使用在後向移動的迭代器中,儘管ListIterator 是一個雙向迭代器

② previousIndex 和 nextIndex 返回值依賴於 cursor 當前的數值,所以 上面代碼中 cursor=0,因此 得出錯誤結果。要想獲取下一個索引的正確之,咱們須要 調用一次 next 函數幫助咱們調整 cursor

這樣便可獲取咱們指望的數值:

 1 public static void main(String[] args) {  2     List<Integer> list = new ArrayList<Integer>(Arrays.asList(4, 5, 6, 7, 8));  3     ListIterator<Integer> it = list.listIterator();  4  System.out.println(it.previousIndex());  5  it.next();  6  System.out.println(it.nextIndex());  7 } 
//output 
-1
1

 

注: previous 和 next 函數中 cusor 移動不同,

next函數是獲取了當前值可是 cursor 已經移動到了下一個,至關於 return array[cursor++];

previous 函數是移動到前一個而且獲取值   ,至關於 return array[--cursor];

相關文章
相關標籤/搜索