1、基本概念java
迭代器是一個對象,也是一種設計模式,Java有兩個用來實實現迭代器的接口,分別是Iterator接口和繼承自Iterator的ListIterator接口。實現迭代器接口的類的對象有遍歷集合對象,選擇集合中的元素和刪除集合中元素的方法。而在使用它時沒必要知道該集合對象底層的結構。Java類庫中實現Iterator接口的迭代器只能正向遍歷集合中的元素,而實現ListIterator接口的迭代器不只可以正向遍歷,還可以反向遍歷集合中的元素。設計模式
2、源碼分析源碼分析
2.一、Iterator接口與ListIterator接口的繼承與實現ui
圖2.1 Java迭代器類的繼承與接口實現(部分)this
ListIterator接口繼承了Iterator接口。在AbstractList、ArrayList和Vector這三個類中的內部類ListItr實現了ListIterator接口,這三個類的內部類ListItr又分別繼承了在這三個類中實現了Iterator接口的內部類Itr。實現ListIterator的類還有LinkedList的內部類ListItr。實現Iterator的類還有LinkedList的內部類DescendingIterator,HashMap的內部類EntryIterator,KeyIterator,ValueIterator,以及TreeMap的內部類PrivateEntryIterator等。spa
2.二、迭代器接口方法設計
1)迭代器的向前移動與向後移動圖解3d
2)Iterator接口方法
code
package java.util; import java.util.function.Consumer; public interface Iterator<E> { boolean hasNext(); /* 在Java中,這個方法的具體實現通常用來在遍歷容器時,調用該方法使迭代器向前移動一位,來檢測集合中是否還有下一個元素,還有下一個元素返回true,不然返回false*/ E next(); /* 實現這個方法,在遍歷容器時,調用該方法將迭代器向前移動一位,並將迭代器越過的一個元素做爲方法的返回值。該方法用來返回集合中下一個元素。
在調用next()方法前,先調用hasNext()方法判斷集合中是否還有下一個元素 */
default void remove() { throw new UnsupportedOperationException("remove"); }
/* 實現這個方法,用來刪除在迭代器調用next()方法迭代器越過的一個元素*/
default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); }
/* 實現這個方法來順序遍歷容器中的每一個元素,用來實現集合類的ForEach遍歷操做*/
}
3)ListIterator接口方法
對象
package java.util; public interface ListIterator<E> extends Iterator<E> { boolean hasNext();//同Iterator接口,用來檢測迭代器前面是否還有元素 E next();
// 同Iterator接口,使迭代器向前移動一位,得到迭代器越過的下一個元素 boolean hasPrevious();
// 實現這個方法來檢測當前迭代器位置後面是否有元素,用於反向遍歷 E previous(); /* 實現這個方法,將迭代器向後移動一位,並將迭代器越過的後面的一個元素做爲方法返回值,在調用該方法前須要調用hasPrevious方法來判斷迭代器前是否有元素 */ int nextIndex();//實現該方法獲取迭代器前面一個元素的索引 int previousIndex();//實現該方法獲取迭代器後面一個元素的索引 void remove(); /* 實現該方法,用來刪除迭代器調用next()方法或調用previous()方法時迭代器越過的一個元素 */ void set(E e);//實現該方法在迭代器遍歷時修改元素 void add(E e);//實現該方法在迭代器遍歷時添加元素 }
2.三、容器類與迭代器的關係
1)Iterator接口。閱讀源碼可知,Collectiion接口實現了Iterable接口,Iterable有一個返回一個Iterator<T>對象的iterator()方法,因此繼承和實現了Collection接口的全部容器類及其子類和實現類都有一個返回Iterator對象的的iterator()方法。Java中有不少容器類中都設計有實現了Iterator接口的內部類,如ArrayList和LinkedList等類。HashMap和TreeMap類中也包含有實現了Iterator的內部類,來對Map中的KeySet、Value和EntrySet進行迭代。Iterable接口的源代碼以下:
public interface Iterable<T> { Iterator<T> iterator();//實現這個方法,該方法返回一個Iterator迭代器對象。
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }//實現這個方法來對容器進行ForEach遍歷 default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
2)ListIterator接口。查看源碼能夠發現,List接口中有兩個返回ListIterator<T>對象的方法,以下。List接口下的的ArrayList和LinkedList都有返回ListIterator對象的方法。
ListIterator<E> listIterator();//實現這個方法,該方法返回一個ListIterator迭代器對象,迭代器初始化後,通常迭代器位於在容器第一個元素後面。 ListIterator<E> listIterator(int index);//實現這個方法,返回一個指定了開始遍歷容器時迭代器初始位置的ListIterator迭代器對象
private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); cursor = index; }
public Iterator<E> iterator() { return listIterator(); } public ListIterator<E> listIterator(final int index) { checkForComodification(); rangeCheckForAdd(index); final int offset = this.offset; return new ListIterator<E>() {//返回了一個ListIterator匿名內部類 int cursor = index; int lastRet = -1; int expectedModCount = ArrayList.this.modCount; public boolean hasNext() { return cursor != SubList.this.size; }
public ListIterator<E> listIterator(int index) { checkPositionIndex(index); return new ListItr(index); } private class ListItr implements ListIterator<E> {
(小官原創,如有謬誤,望各位前輩批評指正)