この記事では、主に Java コレクション フレームワークのイテレーターに関する関連情報を簡単に紹介します。興味のある方は参照してください。
Java の配列データはインデックスを通じて取得できます。物体?インデックス経由でも?今日は、Java コレクション内のコレクション オブジェクトを取得するメソッド iteration-Iterator を分析します。
この記事は主にJavaコレクションフレームワークIteratorのイテレータ部分を分析しています。ソースコード分析はJDK1.8、分析ツールAndroidStudioに基づいています。記事の分析に不備があれば修正してください。
1. はじめに
Java コレクションを反復するために、JDK が提供する反復インターフェースをよく使用します。
Iterator iterator = list.iterator(); while(iterator.hasNext()){ String string = iterator.next(); //do something }
上記は、イテレーターによって使用される基本的なテンプレートです。実際、反復は、さまざまなコンテナー内のすべてのオブジェクトを走査するための標準化されたメソッド クラスであるトラバーサルとして単純に理解できます。これは常に Iterator を制御し、「forward」、「backward」、および「get current element」コマンドを送信して、コレクション全体を間接的に走査します。 Java では、イテレーターは反復のための基本的なルールのみを提供するインターフェースです:
public interface Iterator<E> { //判断容器内是否还有可供访问的元素 boolean hasNext(); //返回迭代器刚越过的元素的引用,返回值是 E E next(); //删除迭代器刚越过的元素 default void remove() { throw new UnsupportedOperationException("remove"); } }
上記はイテレーターの基本的な宣言です。特定のコレクションを通じてそれを分析します。
2. コレクションの分類
2.1 ArrayList のイテレータ
ArrayList のソース コードを分析すると、ArrayList の内部で、次のように、Iterator インターフェイスを実装する内部クラス Itr を最初に定義していることがわかります。
内部的に クラスはIterator インターフェース を実装しており、ArrayList の Iterator は内部クラス Itr を返すため、主に Itr がどのように実装されているかを見ていきます。
private class Itr implements Iterator<E> { //.... }
public Iterator<E> iterator() { return new Itr(); }
private class Itr implements Iterator<E> { protected int limit = ArrayList.this.size; int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor < limit; } @SuppressWarnings("unchecked") public E next() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); int i = cursor; if (i >= limit) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; limit--; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } @Override @SuppressWarnings("unchecked") public void forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = ArrayList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; lastRet = i - 1; if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
protected int limit = ArrayList.this.size; int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount;
public boolean hasNext() { return cursor < limit; }
HashMapのIteratorメソッドを分析します。他のメソッドも同様で、基礎となる実装を把握するだけです。
2.2 HashMapのイテレータ HashMapには、単なる抽象クラスであるHashIteratorを実装するクラスもあります。どのように実装されるかを見てみましょう。
public E next() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); int i = cursor; if (i >= limit) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; }
private abstract class HashIterator<E> implements Iterator<E> { HashMapEntry<K,V> next; // next entry to return int expectedModCount; // For fast-fail int index; // current slot HashMapEntry<K,V> current; // current entry HashIterator() { expectedModCount = modCount; if (size > 0) { // advance to first entry HashMapEntry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } } public final boolean hasNext() { return next != null; } final Entry<K,V> nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); HashMapEntry<K,V> e = next; if (e == null) throw new NoSuchElementException(); if ((next = e.next) == null) { HashMapEntry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } current = e; return e; } public void remove() { if (current == null) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); Object k = current.key; current = null; HashMap.this.removeEntryForKey(k); expectedModCount = modCount; } }
HashMapEntry<K,V> next; // next entry to return int expectedModCount; // For fast-fail int index; // current slot HashMapEntry<K,V> current; // current entry
public final boolean hasNext() { return next != null; }
以上がJavaコレクションフレームワークのイテレータのサンプルコードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。