iterator、for遍歷集合的優缺點
阿新 • • 發佈:2019-02-13
對於在記憶體中儲存空間為連續的集合,如ArrayList、陣列,可以採用以下三種方式進行遍歷:
1、iterator
迭代器遍歷方式, 適用於連續記憶體儲存方式,比如陣列、 ArrayList(其實 ArrayList底層實現也是陣列形式)。 缺點是隻能從頭開始遍歷, 優點是可以邊遍歷邊刪除。
例如:
Iterator iter = list.iterator();
while(iter.hasNext()){
Object o = iter.next();
if(o.equals("a")){
iter.remove();
}
}
2、for each遍歷
底層實現也是基於iterator,所以也只能從頭開始遍歷,效能上比iterator要稍慢一些,因為多了一層型別自動轉換。
3、for list.size方式遍歷
這種方式遍歷比較靈活,可以指定位置開始遍歷。效能最高,但是使用不太優雅,每次都需要在應用程式中手動強轉和額外的獲得list.size,這樣就會導致產生額外的程式碼。
基於for方式的遍歷,還有一個缺點就是遍歷過程中不允許刪除元素,否則會拋ConcurrentModificationException。 如下:
ArrayList<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//list.remove(1);
Iterator iter = list.iterator();
for(String s:list){
if(s.equals("b")){
list.remove(s);
}
}
為什麼用iterator刪除元素不拋異常,而用for刪除會拋異常呢?
這主要是因為arraylist每次遍歷的時候會去判斷該集合是否被修改過,呼叫的方法是checkForComodification()。 如果被修改過ConcurrentModificationException異常。
如何判斷是否修改呢,主要是通過維護2個變數來實現,modCount記錄了修改次數,expectedModCount記錄期望修改次數。 通過iterator.remove()進行的刪除操作,會同時修改modCount、ConcurrentModificationException;
而通過list.remove(object/index),則只會修改modCount。 這也是fast-fail機制。