迭代器(Iterator)是一個對象,它的工作是遍歷並選擇序列中的對象,它提供了一種訪問一個容器(container)對象中的各個元素,而又不必暴露該對象內部細節的方法。通過迭代器,開發人員不需要了解容器底層的結構,就可以實現對容器的遍歷。由於創建迭代器的代價小,因此迭代器通常被稱爲輕量級的容器。
迭代器的使用主要有以下三個方面的注意事項:
1)使用容器的iterator()方法返回一個Iterator,然後通過Iterator的next()方法返回第一個元素。
2)使用Iterator()的hasNext()方法判斷容器中是否還有元素,如果有,可以使用next()方法獲取下一個元素。
3)可以通過remove()方法刪除迭代器返回的元素。
Iterator支持派生的兄弟成員。ListIterator只存在於List中,支持在迭代期間向List中添加或刪除元素,並且可以在List中雙向滾動。
Iterator的使用方法如下例所示:
package com.js;
/**
* Iterator使用Demo
*/
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class Test {
public void main(String[] args){
List<String> ll = new LinkedList<String>();
ll.add("first");
ll.add("second");
ll.add("third");
ll.add("fourth");
for(Iterator<String> iterator = ll.iterator();iterator.hasNext();){
String string = (String)iterator.next();
System.out.println(string);
}
}
}
運行結果爲:
first
second
third
fourth
使用iterator()方法時經常會遇到ConcurrentModificationException異常,這通常是由於在使用Iteraor遍歷容器的同時又對容器做增加或刪除操作所導致的,或者由於多線程操作導致,當一個線程使用迭代器遍歷容器的同時,另外一個線程對這個容器進行增加或刪除操作。下列主要介紹單線程拋出ConcurrentModificationException的情況:
package com.js;
/**
* Iterator使用Demo
*/
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class Test {
public void main(String[] args){
List<String> ll = new LinkedList<String>();
ll.add("first");
ll.add("second");
ll.add("third");
ll.add("fourth");
for(Iterator<String> iterator = ll.iterator();iterator.hasNext();){
String string = (String)iterator.next();
System.out.println(string);
if(string.equals("second"))
ll.add("fifth");// 拋出:ConcurrentModificationException
}
}
}
運行結果爲:
first
second
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
at java.util.LinkedList$ListItr.next(Unknown Source)
at com.js.Test.main(Test.java:17)
拋出上述異常的主要原因是:
在使用Iterator的時候,迭代器會新建一個線程,把原來的線程中的對象重新拷貝一份,在進行刪除,修改等操作時,原來的線程只負責迭代,而Iterator負責迭代和刪除操作,Iterator每次迭代都會檢查迭代器裏的對象和原線程中的對象個數是否一致,不一致則拋出:ConcurrentModificationException。
解決辦法 :
不能使用集合中的remove方法,使用Iterrator中的remove方法。
Iterator中的remove
default void remove()
從基礎集合中移除這個迭代器返回的最後一個元素(可選操作)。兩個線程中都刪除,保證線程的同步。
使用迭代器對象調用其中的remove方法,以保證線程同步。
正確使用方法:
for (Iterator<String> iterator : ll.iterator() ) {
String string = (String)iterator.next();
if(string.equals("second"))
iterator.remove();
}