Java コレクション フレームワーク - リスト、セット、マップ

 1. Java コレクション フレームワークの概要:

1.1 コレクションインターフェイスの継承ツリー

 JDK によって提供されるコレクション API は、java.util パッケージにあります。

 マップインターフェイスの継承ツリー

 1.2 収集インターフェースのメソッド

コレクションインターフェース

Collection インターフェイスは、List、Set、および Queue インターフェイスの親インターフェイスであり、このインターフェイスで定義されたメソッドを使用して、Set コレクションと List および Queue コレクションの両方を操作できます。

JDK は、このインターフェースの直接実装を提供しませんが、より具体的なサブインターフェース (Set や List など) の実装を提供します。

Java5 より前では、Java コレクションはコンテナ内のすべてのオブジェクトのデータ型を失い、すべてのオブジェクトをオブジェクト型として扱いましたが、JDK 5.0 でジェネリックを追加した後は、Java コレクションはコンテナ内のオブジェクトのデータ型を記憶できるようになりまし

コレクションインターフェースメソッド

1.3 イテレータインターフェース

        Iteratorインターフェースを使用してコレクション要素を走査する

        Iterator オブジェクトはイテレーター (デザイン パターンの一種) と呼ばれ、主にコレクション内の要素を走査するために使用されます。

        GOF では、イテレータ パターンを次のように定義しています。オブジェクトの内部詳細を公開せずに、コンテナ オブジェクト内の各要素にアクセスするメソッドを提供します。イテレータ パターンはコンテナのために生まれました。「バスの車掌」、「電車の車掌」、「スチュワーデス」に似ています。

        Collection インターフェースは、 iterator() メソッドを持つ java.lang.Iterable インターフェースを継承しており、Collection インターフェースを実装するすべてのコレクション クラスには、Iterator インターフェースを実装するオブジェクトを返す iterator() メソッドがあります。

        Iterator はコレクションを走査するためにのみ使用され、Iterator 自体にはオブジェクトを保持する機能はありません。Iterator オブジェクトを作成する必要がある場合は、反復処理するコレクションが必要です。

        コレクション オブジェクトに対して iterator() メソッドが呼び出されるたびに、新しいイテレータ オブジェクトが取得され、デフォルトのカーソルはコレクションの最初の要素の前に置かれます。

        Iteratorインターフェースのメソッド

 

 it.next() メソッドを呼び出す前に、検出のために It.hasNext() を呼び出す必要があります。呼ばれなかったら、そして

次のレコードは無効です。it.next() を直接呼び出すと、NoSuchElementException 例外がスローされます。

        イテレータインターフェースのremove()メソッド

イテレータ iter = coll.iterator();// 開始点に戻る

while ( iter .hasNext()){

        オブジェクト obj = iter.next();

        if ( obj .equals( "トム" )){

        iter.remove();

        }

}

知らせ:

        Iterator はコレクションの要素を削除できますが、コレクション オブジェクトの Remove メソッドではなく、トラバーサル プロセス中に Iterator オブジェクトの Remove メソッドを使用します。

        next() が呼び出されていない場合、または next メソッドの最後の呼び出し後に Remove メソッドが呼び出された場合、remove を再度呼び出すと IllegalStateException が報告されます。

         foreachループを使用してコレクション要素を反復処理する

Java 5.0 は、コレクションと配列に反復的にアクセスするための foreach ループを提供します。

トラバーサル操作では、コレクションまたは配列の長さを取得する必要はなく、要素にアクセスするためにインデックスを使用する必要もありません。

コレクションを走査する基礎となる層は、Iterator を呼び出して操作を完了します。

foreach を使用して配列を反復処理することもできます。

 2. Collectionサブインターフェースの 1 つ: Listインターフェース

2.1 リストインターフェースの概要

データを保存するための Java の配列の制限を考慮して、通常は配列の代わりに List を使用します。

List コレクション クラスの要素は順序付けされており、繰り返し可能です。コレクション内の各要素には、対応する順次インデックスがあります。

List コンテナ内の各要素は、コンテナ内での位置を記録する整数のシリアル番号に対応しており、コンテナ内の要素はシリアル番号に従ってアクセスできます。

JDK API で一般的に使用される List インターフェイスの実装クラスは、ArrayList、LinkedList、Vector です。

2.2 リストインターフェースメソッド

2.3 List 実装クラスの 1 つ: ArrayList

ArrayList は、List インターフェイスの代表的な実装クラスであり、主要な実装クラスです。

基本的に、ArrayList はオブジェクト参照の「可変長」配列です。

JDK1.8以前とJDK1.8以降のArrayList実装の違いは何ですか?

        JDK1.7: ArrayList は腹を空かせた中国人のようなもので、初期容量 10 の配列を直接作成します。

        JDK1.8: ArrayList は怠け者のようなもので、最初に長さ 0 の配列を作成し、最初の要素が追加されたときに初期容量 10 の配列を作成します。

Arrays.asList(…) メソッドによって返される List コレクションは、ArrayList インスタンスでも Vector インスタンスでもありません。

Arrays.asList(…) の戻り値は固定長のリストです。

ArrayList は動的配列です。

利点: 基礎となるデータ構造は配列であるため、クエリは高速ですが、追加と削除は低速です。

短所: スレッドは安全ではない、高効率。
 

2.3.1 ArrayList コンストラクター

2.3.2   ArrayList 方法

public class Test01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("a");
        System.out.println(list);
        System.out.println(list.get(1));
        System.out.println("list集合遍历:");
        /*
        for (int i = 0;i< list.size();i++){
            String s = list.get(i);
            System.out.println(s);
        }
         */
        //增强for循环
        for (String s :list){
            System.out.println(s);
        }

    }
}

 ArrayListについては別のブログで書いているのでここでは説明しません。 

2.4 リスト実装クラス 2: LinkedList

要素の挿入または削除を頻繁に行う場合は、より効率的な LinkedList クラスを使用することをお勧めします。

LinkedList は、リンク リストに基づいたストレージ構造です。

LinkedList:二重リンク リスト。内部で配列は宣言されていませんが、最初と最後の要素を記録するために使用される Node タイプの最初と最後が定義されています。同時に、LinkedListにデータを格納するための基本構造として内部クラスNodeを定義します。データの保存に加えて、Node は 2 つの変数も定義します。

        prev 変数は、前の要素の位置を記録します。

        next 変数は、次の要素の位置を記録します。

利点: 基礎となるデータ構造はリンク リストであるため、クエリは遅くなり、追加と削除は高速になります。

短所: スレッドは安全ではない、高効率

2.4.1 LinkedList コンストラクター

2.4.2 LinkedList メソッド

 2.5 リスト実装クラス 3: ベクトル

Vector は JDK1.0 に存在した古いコレクションです。Vector がスレッドセーフであることを除いて、ほとんどの操作は ArrayList の場合と同じです。

さまざまなリストの中で、デフォルトの選択肢として ArrayList を使用するのが最善です。挿入と削除が頻繁に行われる場合は、LinkedList を使用します。Vector は常に ArrayList よりも遅いため、使用は避けてください。

利点: 基礎となるデータ構造は配列であるため、クエリは高速ですが、追加と削除は低速です。

短所: スレッドの安全性、低効率。

2.5.1ベクトルフィールド

 2.5.2 ベクトル構築法

 2.5.3 ベクトル法

 

ArrayList と LinkedList の類似点と相違点

どちらもスレッドアンセーフですが、比較的スレッドセーフな Vector は実行効率が高くなります。

さらに、ArrayList は動的配列に基づいたデータ構造を実装し、LinkedList はリンク リストに基づいたデータ構造を実装します。LinkedList はポインタを移動する必要があるため、ランダム アクセスで取得および設定する場合は、LinkedList よりも ArrayList の方が優れています。ArrayList はデータを移動する必要があるため、追加と削除 (特に挿入) と削除の場合は LinkedList が有利です。

3. Collectionサブインターフェースの 1 つ: Setインターフェース

Set インターフェイスは Collection のサブインターフェイスであり、追加のメソッドは提供されません。

Set コレクションに同じ要素を含めることはできません。2 つの同一の要素を同じ Set コレクションに追加しようとすると、追加操作は失敗します。

Set は、== 演算子を使用する代わりに、equals() メソッドに基づいて 2 つのオブジェクトが同じかどうかを判断します。

3.1  Set実装クラスの 1 つ: HashSet

HashSet は Set インターフェイスの典型的な実装であり、この実装クラスは Set コレクションを使用するときにほとんどの場合に使用されます。

HashSet はハッシュ アルゴリズムに従って要素をセットに格納するため、アクセス、検索、削除のパフォーマンスが優れています。

HashSet には次の特徴があります。

        要素の順序は保証されません

        HashSet はスレッドセーフではありません

        コレクション要素は null になる可能性があります

HashSetコレクション内の 2 つの要素が等しいかどうかを判断するための基準: 2 つのオブジェクトは hashCode() メソッドによって等しいかどうかが比較され、2 つのオブジェクトの equals() メソッドの戻り値も等しいです。

Set コンテナに格納されたオブジェクトの場合、対応するクラスは、オブジェクトの等価性ルールを実装するために、equals() メソッドhashCode(Object  obj)メソッドをオーバーライドする必要があります。つまり、「等しいオブジェクトには等しいハッシュ コードが必要である」ということです。

HashSet に要素を追加するプロセス:

        要素を HashSet コレクションに格納するとき、HashSet はオブジェクトの hashCode() メソッドを呼び出してオブジェクトの hashCode 値を取得し、特定のハッシュ関数を使用して基になる配列内のオブジェクトの格納場所を決定します。 hashCode 値に基づく HashSet。(このハッシュ関数は、配列内の添え字を取得するために、基礎となる配列の長さを使用して計算されます。また、このハッシュ関数の計算により、要素を可能な限り均等に格納できるようになります。ハッシュ分布が大きいほど、より良い結果が得られます。ハッシュ関数は設計されています。良い)。

        2 つの要素の hashCode() 値が等しい場合、equals メソッドは引き続き呼び出されます。equals メソッドの結果が true の場合、追加は失敗します。false の場合、要素は保存されますが、すでに配列の位置に要素がある場合は、リンク リストを介してリンクを続行します。

2 つの要素の equals() メソッドが true を返しても、それらの hashCode() の戻り値が等しくない場合、hashSet はそれらを異なる場所に保存しますが、それでも正常に追加できます。

hashCode()メソッドをオーバーライドするための基本原則

        プログラムの実行中に、同じオブジェクトに対して hashCode() メソッドを複数回呼び出すと、同じ値が返されるはずです。

        2 つのオブジェクトの equals() メソッドの比較が true を返す場合、2 つのオブジェクトの hashCode() メソッドの戻り値も等しい必要があります。

        quals() メソッドによる比較に使用されるオブジェクト内のフィールドは、hashCode 値の計算に使用する必要があります。

3.1.1 HashSetの構築方法

 3.1.2 HashSet 方法

public class Test01 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("x");
        set.add("y");
        set.add("z");
        set.add("x");
        System.out.println(set);
        System.out.println("set集合的遍历:");
        //set集合用迭代器来遍历
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            String s = iterator.next();
            System.out.println(s);
        }

    }
}

 3.2 実装クラス 2の設定: LinkedHashSet

LinkedHashSet は HashSet のサブクラスです。

LinkedHashSet は、hashCode 値に基づいて要素の保存場所を決定しますが、要素の順序を維持するために二重リンク リストも使用します。これにより、要素が挿入順に保存されているように見えます。

LinkedHashSet の挿入パフォーマンスは HashSet よりもわずかに低くなりますが、Set 内のすべての要素に反復的にアクセスする場合は良好なパフォーマンスを発揮します。

LinkedHashSet では、セット要素の重複は許可されません。

3.2.1 LinkedHashSetの構築方法

3.3 セット実装クラス 3: TreeSet

TreeSet は SortedSet インターフェイスの実装クラスであり、コレクション要素がソートされた状態であることを保証します。

TreeSet の最下層は、赤と黒のツリー構造を使用してデータを保存します。

TreeSet には、自然な並べ替えカスタマイズされた並べ替えという2 つの並べ替え方法があります。デフォルトでは、TreeSet は自然な順序付けを使用します。

4. Collectionサブインターフェースの 1 つ: Mapインターフェース

  マップインターフェースの概要

マップとコレクションは並列して存在します。マッピング関係(キーと値) を使用してデータを保存するために使用されます。

Map のキーと値はどちらも、任意の参照型のデータにすることができます。

Map 内のキーは Set に格納され、重複は許可されません。つまり、同じ Map オブジェクトに対応するクラスは hashCode() メソッドとquals() メソッドをオーバーライドする必要があります。

String クラスは、Map の「キー」としてよく使用されます。

キーと値の間には一方向の 1 対 1 の関係があります。つまり、一意で特定の値は、指定されたキーを通じて常に見つけることができます。

Map インターフェイスの共通実装クラス: HashMap、TreeMap、LinkedHashMap、Properties。その中でも、HashMap は、Map インターフェースの実装クラスとして最も頻繁に使用されます。

 4.1 マップインターフェイス: 一般的なメソッド

 4.2  Map実装クラスの 1 つ: HashMap

HashMap は、Map インターフェイスの最も頻繁に使用される実装クラスです。

Null キーと Null 値が許可され、HashSet と同様に、マッピングの順序は保証されません。

すべてのキーで構成されるセットは、順序付けされておらず、反復不可能です。したがって、キーが配置されているクラス (equals() と hashCode()) を書き直す必要があります。

すべての値のコレクションはコレクションです。順序付けされておらず、繰り返し可能です。したがって、value が配置されているクラスを、equals() のように書き直す必要があります。

Key-Value がエントリを構成します。

すべてのエントリで構成されるセットは、順序付けされておらず、反復不可能であるセットです。

HashMapが 2 つのキーが等しいと判断する基準は、2 つのキーが equals() メソッドを通じて true を返し、hashCode の値も等しいということです。

HashMapが 2 つのが等しいと判断する基準は、equals() メソッドを通じて 2 つの値が true を返すことです。

4.2.1 HashMapの構築方法

 4.2.2 HashMapメソッド

public class Test01 {
    public static void main(String[] args) {
        //创建一个map key为string类型 数据是object类型
        Map<String,Object> map = new HashMap<>();
        //添加数据,通过key
        map.put("name","张三");
        map.put("age",20);
        map.put("sex","男");
        System.out.println("Map集合的遍历:");
        //通过keyset获取map中所有key值并把它们保存在set集合
        Set<String> ks = map.keySet();
        //迭代器
        Iterator<String> i = ks.iterator();
        //用hasNext查找key
        while (i.hasNext()){
            //获取key值
            String key = i.next();
            Object value = map.get(key);
            System.out.println(key+"--->"+value);
        }
    }
}

4.3 マップ実装クラス 2: Linked HashMap

LinkedHashMap は HashMap のサブクラスです。

HashMap の記憶構造に基づいて、要素が追加される順序を記録するために、二重にリンクされた一対のリストが使用されます。

LinkedHashSet と同様に、LinkedHashMap はマップの反復順序を維持できます。反復順序は Key-Value ペアの挿入順序と一致します。

4.3.1 LinkedHashMapの構築方法

 4.3.2 LinkedHashMap メソッド

4.4 マップ実装クラス 3: TreeMap

TreeMap が Key-Value ペアを格納する場合、Key-Value ペアに従って並べ替える必要があります。

TreeMap は、すべての Key-Value ペアが順序付けられた状態        であることを保証します

TreeSet の最下層は、赤と黒のツリー構造を使用してデータを保存します。

TreeMap のキーの並べ替え:

        自然な並べ替え: TreeMap 内のすべてのキーは Comparable インターフェイスを実装する必要があり、すべてのキーは同じクラスのオブジェクトである必要があります。そうしないと、ClasssCastException がスローされます。

        カスタマイズされた並べ替え: TreeMap を作成するときに、TreeMap 内のすべてのキーを並べ替える役割を担う Comparator オブジェクトを渡します。現時点では、マップのキーで Comparable インターフェイスを実装する必要はありません。

2 つのキーが等しいかどうかを判断するためのTreeMap の基準: 2 つのキーは、compareTo() メソッドまたは Compare() メソッドを通じて 0 を返します。

4.4.1 TreeMapの構築方法

 4.4.2 TreeMap メソッド

4.5 マップ実装クラス 4: ハッシュテーブル

Hashtable は、JDK1.0 によって提供される古代の Map 実装クラスです。HashMap とは異なり、Hashtable はスレッドセーフです。

Hashtable の実装原理は HashMap と同じであり、機能も同じです。最下位層はハッシュ テーブル構造を使用し、クエリ速度が速く、多くの場合相互運用できます。

HashMap とは異なり、Hashtable ではキーと値として null を使用できません。

HashMap と同様、Hashtable は Key-Value ペアの順序を保証しません。

2 つのキーが等しいか、2 つの値が等しいかを判断する Hashtable の基準は、HashMap と一致しています。

4.5.1 ハッシュテーブルの構築方法

4.5.2 ハッシュテーブル方式

 4.6 マップ実装クラス 4: プロパティ

Properties クラスは、プロパティ ファイルの処理に使用されるオブジェクトである Hashtable のサブクラスです。

プロパティファイルのキーと値は両方とも文字列型であるため、プロパティのキーと値も両方とも文字列型になります。

データにアクセスする場合は、setProperty(String key, String value) メソッドおよび getProperty(String key) メソッドを使用することをお勧めします。

 4.6.1 プロパティの構築方法

4.6.2 プロパティメソッド

5. コレクションツールクラス

CollectionsはSet、List、Mapなどのコレクションを操作するためのツールクラスです。

Collections は、コレクション要素の並べ替え、クエリ、および変更のための一連の静的メソッドを提供し、また、コレクション オブジェクトに不変性を設定し、コレクション オブジェクトに同期制御を実装するためのメソッドも提供します。

ソート操作: (すべて静的メソッド)

        reverse(List): リスト内の要素の順序を逆にします

        shuffle(List): List コレクションの要素をランダムに並べ替えます。

        sort(List): 指定された List コレクション要素を要素の自然な順序に従って昇順に並べ替えます。

        sort(List, Comparator): 指定された Comparator によって生成された順序に従って List コレクション要素を並べ替えます。

        swap(List, int, int): 指定されたリスト コレクション内の i の要素と j の要素を交換します。

 コレクションの共通メソッド: 同期制御

Collections クラスには複数の synchronizedXxx() メソッドが用意されており、指定されたコレクションをスレッド同期コレクションにラップできるため、複数のスレッドがコレクションに同時にアクセスする場合のスレッド セーフティの問題が解決されます。

 

 5.1 回収方法

おすすめ

転載: blog.csdn.net/weixin_67224308/article/details/128121166