セットコレクション(HashSetコレクション)

セットコレクション:繰り返される要素を含まないコレクション。より正確には、セットは、e1.equals(e2)を満たし、null要素を含む要素ペアe1とe2を提供しません。名前が示すように、このインターフェイスは数学的な集合の抽象化を模倣しています。

java.util.Setインターフェースはコレクションインターフェースを拡張します

特徴:

1.重複する要素を保存することは許可されていません

2.インデックスがなく、インデックスを使用するメソッドがなく、通常のforループトラバーサルは使用できません。

一.HashSet

このクラスはSetインターフェイスを実装し、ハッシュテーブル(実際にはHashMapインスタンス)によってサポートされます。セットの反復順序を保証するものではありません。特に、順序が永久に同じままであるという保証はありません。このクラスでは、null要素を使用できます。

この実装も同期的ではありません

public static void main(String [] args){ 
    //多態的な書き込み
    Set <Integer> set = new HashSet <>(); 
    set.add(1); 
    set.add(3); //無秩序、アクセス順序はinconsistent 
    set.add(2); 
    set.add(1); //繰り返される要素
    はありません//通常のforループは使用できません、反復できます。foreachループもできます
    Iterator <Integer> iterator = set。 iterator(); 
    while(iterator.hasNext()){ 
        System.out.println(iterator.next()); // 1 2 3 
    } 
    for(Integer i:set){ 
        System.out.println(i); / / 1 23 
    } 
}

データを格納するためのハッシュセットの構造(ハッシュテーブル)

ハッシュテーブルとは何ですか?

まずハッシュ値(ハッシュ値)を見てみましょう

定義:システムによってランダムに与えられる10進整数(つまり、データが実際に格納されている物理アドレスではなく、オブジェクトのアドレス値、論理アドレス、シミュレートされたアドレス)

Objectクラスには、オブジェクトのハッシュ値を取得するためのメソッドがあります。

public native int hashCode():オブジェクトのハッシュ値を返します

ネイティブ:メソッドがローカルオペレーティングシステムのメソッドを呼び出すことを意味します。

 

public static void main(String [] args){ 
    Person person = new Person(); 
    // PersonクラスはObjectクラスを継承するため、ObjectクラスのhashCodeメソッドを使用できます
    int hash = person.hashCode(); 

    Person person1 = new Person(); 
    int hash1 = person1.hashCode(); 

    / *オブジェクトソースコードのtoStringメソッド:
    public String toString(){ 
    return getClass()。getName()+ "@" + Integer.toHexString( hashCode());}
    出力の後半は、ハッシュアドレス値の16進表現です
     * / 
    // 
    System.out.println(person); // demo08.Person@1b6d3586 
    System.out.println(hash)を比較します; // 460141958 
}

オブジェクトソースコードのtoStringメソッドでは、@ printの後半は、ハッシュアドレス値の16進数であることに注意してください。

しかし、同じことは単なる論理アドレスであり、物理アドレスではありません。

 

同じ論理アドレスが同じ物理アドレスを意味するわけではありません!オブジェクトが異なり、ハッシュアドレスも同じである可能性があります。

例えば:

 

System.out.println(person == person1); // false 
String str = new String( "aaa"); 
文字列str1 = new String( "aaa"); 
System.out.println(str.hashCode()); // 96321 
System.out.println(str1.hashCode()); // 96321
//論理アドレスは物理アドレスと同じではありません
System.out.println(str == str1); // false 

//オブジェクトが異なり、ハッシュアドレスが同じである可能性があります
System.out.println( "重地 ".hashCode()); // 1179395 
System.out.println(" Call ".hashCode()); // 1179395

 

JDK1.8より前は、ハッシュテーブルの最下層は配列+リンクリストによって実装されていました。つまり、リンクリストは競合の処理に使用され、同じハッシュ値のリンクリストはリンクリストに格納されます。ただし、バケット内に要素が多い場合、つまりハッシュ値が等しい要素が多い場合、一度にキー値を検索する効率は低くなります。JDK1.8では、ハッシュテーブルストレージは配列+リンクリスト+赤黒木で実装されています。リンクリストの長さがしきい値(8)を超えると、リンクリストは赤黒木に変換されます。検索時間を短縮します。

簡単に言えば、ハッシュテーブルは配列+リンクリスト+赤黒木によって実装されます(JDK1.8は赤黒木部分を追加します)。

説明に示されているように:

 

HashSetでは要素の繰り返しが許可されないという原則を学びましょう。

// HashSetコレクションを作成します
HashSet <String> hashSet = new HashSet <>(); 
//要素を格納しますStringstr1 = new 
String( "aaa"); 
String str2 = new String( "aaa"); 
hashSet.add(str1 ); 
hashSet.add(str2); 
hashSet.add( "heavy Ground"); 
hashSet.add( "call"); 
hashSet.add( "aaa"); 
System.out.println(hashSet); // [aaa 、重い地面、電話]

 

 

HashSetはカスタムタイプの要素を格納します

整数型と文字列型のデータをHashSetに格納します。これらのデータ型はすべて定義済みの型であり、hashCodeメソッドとequalsメソッドはオーバーライドされます。カスタム型要素を格納するにはどうすればよいですか?

また、hashCodeメソッドとequalsメソッドを書き直してください!

HashSetのカスタム型要素を格納するときは、オブジェクトのhashCodeメソッドとequalsメソッドを書き直し、独自の比較メソッドを確立して、HashSetコレクション内のオブジェクトが一意であることを確認する必要があります。

書き換え方法がない場合:

public static void main(String [] args){ 
    // Personを格納するHashSetコレクションを作成します
    HashSet <Person> hashSet = new HashSet <>(); 

    Person p1 = new Person( "易烊千玺"); 
    Person p2 = new Person( "王俊凯"); 
    Person p3 = new Person( "易烊千玺"); 
    hashSet.add(p1); 
    hashSet.add(p2); 
    hashSet.add(p3); 

    System.out.println(p1) .hashCode()); // 460141958 
    System.out.println(p3.hashCode()); // 1956725890 
    System.out.println(p1.equals(p3)); // false 
    // equalsメソッドとhashCodeメソッドの場合オーバーライドされません
    //印刷[Person {name = 'Yiyang Qianxi'}、Person {name = '王俊凯'}、Person {name = 'Yiyang Qianxi'}] 
    //同じ有名人を識別できません
    System.out.println( hashSet); 
}

メソッドを書き直した後:

@Override 
public boolean equals(Object o){ 
    if(this == o)return true; 
    if(o == null || getClass()!= o.getClass())はfalseを返します; 
    人人=(人)o; 
    Objects.equals(name、person.name);を返します。
} 

@Override 
public int hashCode(){ 
    return Objects.hash(name); 
}
System.out.println(p1.hashCode()); // 806906957 
System.out.println(p3.hashCode()); // 806906957 
System.out.println(p1.equals(p3)); // true 

System.out.println(hashSet); // [Person {name = '王俊凯'}、Person {name = '易烊千玺'}]

 

おすすめ

転載: blog.csdn.net/wardo_l/article/details/113990846