Java Iterator(反復器)学習ノートについて

4769 ワード

「反復」はJavaプログラマーにとってよく知られていないと信じられています(もちろん、他の言語のプログラマーもそうです).データを処理する際には、データに対する多くの遍歴操作が避けられません.私自身にとって、Java言語を2年間勉強し、「反復」に対しての概念は、for:eachfor:iの遍歴段階にも留まっている.今日はJDKが提供する反復インタフェースを用いてJava集合の反復を行い,メモをとり,後で学習することにした.
通常のJavaコレクション反復(遍歴)
反復は単純に遍歴として理解でき、JDKが反復器を提供していない場合、データの遍歴処理は次のようになります.
  • 配列に対する遍歴処理:
  • Bean[] beans = new Bean[5];
    
    for (int i = 0; i < beans.length; i++) {
        beans[i] = new Bean();
        // todo something
    }
    
  • 対ArrayListの遍歴処理:
  • ArrayList beanArrayList = new ArrayList();
    for (int i = 0; i < beanArrayList.size(); i++) {
        beanArrayList.add(new Bean());
        // todo something
    }
    

    空のJavaコレクションにデータを追加したい場合はでは、この集合の内部のデータ構造(すなわち、配列とArrayListを例にとると、追加時の操作はbeans[i] = new Bean();であるべきかbeanArrayList.add(new Bean());であるべきか)を知る必要があります.これにより、アクセスロジックが集合の構造自体と密接に結合し(すなわち、異なるデータセットごとに異なる便利な方法に対応している)、コードが多重化できなくなります.Iteratorは上記問題を簡単に解決することができる.
    java.util.Iterator
    公式に出ていない説明を見てみましょう.public interface Iterator An iterator over a collection. Iterator takes the place of Enumeration in the Java Collections Framework. Iterators differ from enumerations in two ways:
  • Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
  • Method names have been improved. This interface is a member of the Java Collections Framework

  • すなわち、Iteratorはcollectionの集合を反復する反復器(インタフェース)である.Iterator反復器はJava Collections FrameworkのEnumerationに取って代わった.このインタフェースはJava Collections Frameworkのメンバーである.反復器は列挙と2つの点が異なる.
  • 反復器は、反復中に反復器が指すcollectionから要素を削除するために、呼び出し元が定義された良好な意味を利用することを可能にする.
  • メソッド名が改良された.

  • これは、Iteratorが同じアクセスロジックを使用して集合の遍歴を完了することを意味し、集合要素にアクセスするときに、異なる集合の内部構造に関心を持つ必要がないことを意味する.これにより、アクセスロジックとコレクション自体の結合度が低下する.Iteratorインタフェースのソースコードは次のとおりです.
    package java.util;
    
    import java.util.function.Consumer;
    
    public interface Iterator {
        //             。
        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()の方法を用いて簡単な反復(以前のスキームと同様)を完了することができる.
    Iterator beanIterator = beanArrayList.iterator();
    while (beanIterator.hasNext()) {
        Bean bean = beanIterator.next();
        // todo something
    }
    

    2017.12に更新.03
    それだけで前の案と変わらないのではないでしょうか.もちろん、できることはもっとあります.集合の内部構造に本当に関心を持たない反復手段を実現します.次のコードは、集合オブジェクトに対する反復です.
    public static boolean isExist(Collection beans, Bean bean) {
        Iterator iterator = beans.iterator();
        System.out.println(beans.getClass().getSimpleName() + ":");
        while (iterator.hasNext()) {
            if (iterator.next().equals(bean)) {
                System.out.println("       Bean[" + bean + "]");
                return true;
            }
        }
    
        return false;
    }
    

    Test:
    public static final void main(String[] args) {
        Bean bean0 = new Bean().setId("01");
        Bean bean1 = new Bean().setId("02");
        
        ArrayList beanArrayList = new ArrayList<>();
        Queue beanQueue = new LinkedBlockingQueue<>();
        HashMap map = new HashMap<>();
    
        beanArrayList.add(bean0);
        beanArrayList.add(bean1);
    
        map.put(bean0, bean0);
        map.put(bean1, bean1);
    
        beanQueue.add(bean0);
        beanQueue.add(bean1);
    
        isExist(map.keySet(), bean0);
        isExist(beanArrayList, bean1);
        isExist(beanQueue, bean1);
    }
    

    出力結果:
    KeySet:
               Bean[Bean{id='01', password='null'}]
    ArrayList:
               Bean[Bean{id='02', password='null'}]
    LinkedBlockingQueue:
               Bean[Bean{id='02', password='null'}]
    

    まとめ
    すべてのCollectionフレームワークのjのほとんどの集合クラス(またはインタフェース)(例えばArrayList,Set,Queueなど)は、独自の内部の反復器を実現している(インタフェースもiterator()メソッドを宣言している)が、Iteratorの実現であることは間違いない.
    しかし、私が今知っている限りでは、配列はそれ自体の実装案が「コンパイル処理とJVMのnative()メソッドに関係しているため、それ自体の反復器を直接取得することはできないようです.どなたか方法を知っている方は、コメントをお願いします.感謝に堪えません.
    学習ノートを書くのは初めてで、これからも続けていきたいと思っています.