私は、次の方法のterableに1つのインターフェイスだけを持っている- 私の teratorを
パブリックインターフェイスのIterable
{
パブリック抽象イテレータイテレータ();
}
コレクションは、継承されたI terableインタフェースを
イテレータ<E>反復子();
リストには、Collectionインタフェースを継承しました
ArrayListのは、リストのインターフェイスを実装します
公共イテレータ<E>反復子(){
新しいのITR()を返します。
}
返すイテレータオブジェクト、オブジェクトの実装クラスIteratorインターフェイス継承
- Iteratorインターフェイス
パブリックインターフェイスイテレータ
{
パブリック抽象ブールのhasNext();
次のパブリック抽象オブジェクト();
公共の抽象無効のremove();
}
プライベートクラスItrが実装するIterator <E> {
int型のカーソル。//次の要素のインデックスが返されます
int型lastRet = -1; //最後の要素のインデックスが返さ。-1はそのような場合
int型expectedModCount = modCount。
//は、合成コンストラクタを作成防ぎます
香料(){}
パブリックブールのhasNext(){
カーソルを返す=サイズ!;
}
@SuppressWarnings( "未チェック")
公共E次の(){
checkForComodification();
私は、カーソル= int型。
(I> =サイズ)の場合
新しいはNoSuchElementExceptionを投げます();
オブジェクト[]からelementData = ArrayList.this.elementData。
もし(I> = elementData.length)
新しいConcurrentModificationExceptionをスロー();
カーソル= I + 1。
リターン(E)からelementData [lastRet = I]。
}
公共のボイドのremove(){
(lastRet <0)の場合
新しいIllegalStateExceptionがスロー();
checkForComodification();
{試します
ArrayList.this.remove(lastRet)。
カーソル= lastRet。
lastRet = -1;
expectedModCount = modCount。
}キャッチ(例外:IndexOutOfBoundsException EX){
新しいConcurrentModificationExceptionをスロー();
}
}
@オーバーライド
公共のボイドforEachRemaining(消費者<?スーパーE>アクション){
Objects.requireNonNull(アクション)。
最終int型のサイズ= ArrayList.this.size。
私は、カーソル= int型。
{(I <サイズ)なら
最後の目的は、[] =からelementDataです。
もし(I> = es.length)
新しいConcurrentModificationExceptionをスロー();
(; I <サイズ&& modCount == expectedModCount; I ++)について
action.accept(elementAt(ES、i))を、
//更新ヒープ書き込みトラフィックを減らすために最後に一度
カーソル= I;
lastRet = I - 1。
checkForComodification();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
另外for each,反编译后
Integer i;
for(Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(i)){
i = (Integer)iterator.next();
}
其实就是依赖Iterator迭代器
(只要实现了Iterable接口,就可以直接使用foreach)
一个小问题: 为什么不直接将hasNext(),next()方法放在Iterable接口中,其他类直接实现就可以了??
答: 原因是有些集合类可能不止一种遍历方式,实现了Iterable的类可以再实现多个Iterator内部类,例如LinkedList中的ListItr和DescendingIterator两个内部类,就分别实现了双向遍历和逆序遍历。通过返回不同的Iterator实现不同的遍历方式,这样更加灵活。如果把两个接口合并,就没法返回不同的Iterator实现类了。