對於Collection類下的集合如各類List各類Set,用於實現這些集合的數據結構各不相同,好比數組實現的ArrayList、鏈表實現的LinkedList,當客戶端知道要使用的集合的底層結構的時候能夠選擇相應的遍歷方式。java
好比客戶端知道ArrayList是用數組實現的,可使用遍歷數組的方式遍歷ArrayList。若是客戶端須要遍歷的容器類型發生了變換可能就不能或者不適合使用先前的遍歷方式,好比若是把ArrayList換成LinkedList,雖然仍然可使用這種方式遍歷但性能大大下降;若是換成某個set,甚至不能使用這種方式遍歷。設計模式
ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); }
爲了提升代碼的通用性減少耦合性,在客戶端和容器之間新增了一個新的角色:迭代器,迭代器負責屏蔽了各類Collection實現類的區別,採用一樣的迭代器語法能夠遍歷Collection的全部子類,這樣以來客戶端的代碼無需關心集合類的具體實現。數組
Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } Iterator<Integer> linkIterator = list2.iterator(); while (linkIterator.hasNext()){ System.out.println(linkIterator.next()); } Iterator<Integer> setIterator = set.iterator(); while (setIterator.hasNext()){ System.out.println(setIterator.next()); }
迭代器往小了說是一種遍歷集合的方式,往大了說他也是一種設計模式。數據結構
能夠猜出迭代器應該是某種接口,並且是應該靠近Collection繼承體系頂層的接口,由於Collection集合下的全部類是通用的。性能
public interface Iterable<T> { Iterator<T> iterator();
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
iterable接口中第一個方法用來返回iterator對象,兩者的名字很像。從英語語法的角度分析iterable是一個形容詞表明實現了該接口的對象有可迭代的能力,iterator是一個名詞是具體迭代的執行者又稱迭代器。實現了iterable接口的集合對象經過返回的iterator實現了對該集合的迭代。剩下兩個方法的jdk-1.8中新增的,它們使用default關鍵字修飾。default關鍵字容許在接口中定義方法,且不要求實現了該接口的類實現該方法。 ui
package java.util; import java.util.function.Consumer; /** public interface Iterator<E> { boolean hasNext();
E next();
default void remove() { throw new UnsupportedOperationException("remove"); } default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }
關注的重點是iterator方法,hasNext方法用於判斷集合中是否存在下一個元素,next用於取出下一個元素;剩下的兩個default修飾的方法是jdk-1.8新增的。this