ArrayList的迭代器和 超強for迴圈
阿新 • • 發佈:2018-12-25
超強for迴圈 也是用迭代器實現的。
有個面試官,問去除ArrayList的一些元素,當時寫的是for迴圈,判斷去除,然後左邊退一位。他說不安全。
用迭代器遍歷安全,迭代器包含一個remove方法,去除元素後自帶遊標退一位。
主要三個方法,hasnext,next,和remove
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") 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]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }
轉載:https://blog.csdn.net/H_Gao/article/details/52901297
package com.wind.gaohui;
import java.util.ArrayList;
import java.util.List;
public class TestFor {
public static void main(String[] args) {
List<String> lists = new ArrayList<String>();
if(lists.size()>0) {
for (String str : lists) {
System.out.println(str.toString());
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
首先,來看上面一段程式碼片段,對於一個空的集合,使用增強for迴圈遍歷的時候,我們是不是需要對集合的size進行判斷以防止出現空指標的異常呢?
之前一直以為這是必須的,直到最近親手測試了下,發現對集合的size判斷完全是沒有必要的。
其實,增強for迴圈的內部其實就是用Iterator來實現的。
那麼何以見得呢?
package com.wind.gaohui;
import java.util.ArrayList;
import java.util.List;
public class TestFor {
public static void main(String[] args) {
List<String> lists = new ArrayList<String>();
for(String str : lists) {
System.out.println(str.toString());
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
針對上面這行程式碼,我們使用javap來檢視編譯生成的位元組碼如下圖:
-c引數表示對這段程式碼進行反編譯。
package com.wind.gaohui;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class TestIterator {
public void testIterator() {
List<String> lists = new ArrayList<String>();
Iterator<String> strs = lists.iterator();
while(strs.hasNext()){
System.out.println(strs.next());
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
接著我們用Iterator的方式遍歷這個空的結合,再用javap工具對這段Iterator的程式碼進行反編譯,
得到如下的結果:
我們發現增強for迴圈遍歷和iterator遍歷反編譯後的位元組碼完全一樣,這樣,我們就大概明白了增強for迴圈實際上內部就是iterator。
由於使用iterator機制,所以在遍歷的時候根本不需要進行size大小的判斷,因為iterator機制中就進行了判斷,strs.hasNext(),當這個遊標最開始在集合最前面的時候,就會判斷下一個位置是否有元素