logo

Javaのハッシュセット

Java ハッシュセット クラスは Set インターフェイスを実装し、実際には HashMap インスタンスであるハッシュ テーブルをサポートします。ハッシュ セットの反復順序については保証されません。これは、クラスが時間の経過とともに要素の一定の順序を保証しないことを意味します。このクラスは null 要素を許可します。このクラスは、ハッシュ関数がバケット間で要素を適切に分散すると仮定して、追加、削除、包含、サイズなどの基本的な操作に対して一定時間のパフォーマンスも提供します。これについては、この記事でさらに詳しく説明します。

Java ハッシュセットの機能

HashSet のいくつかの重要な機能を以下に示します。

  • 器具 インターフェースの設定
  • HashSet の基礎となるデータ構造は次のとおりです。 ハッシュ表
  • Set インターフェイスを実装しているため、重複した値は許可されません。
  • HashSet に挿入するオブジェクトは、同じ順序で挿入されるとは限りません。オブジェクトはハッシュ コードに基づいて挿入されます。
  • HashSet では NULL 要素が許可されます。
  • HashSet も実装します シリアル化可能 そして クローン可能 インターフェース。

HashSetの宣言

public class HashSet extends AbstractSet implements Set, Cloneable, Serializable>

どこ そして HashSet に格納される要素のタイプです。



HashSet Java の例

ジャワ




// Java program to illustrate the concept> // of Collection objects storage in a HashSet> import> java.io.*;> import> java.util.*;> > class> CollectionObjectStorage {> > >public> static> void> main(String[] args)> >{> >// Instantiate an object of HashSet> >HashSet set =>new> HashSet();> > >// create ArrayList list1> >ArrayList list1 =>new> ArrayList();> > >// create ArrayList list2> >ArrayList list2 =>new> ArrayList();> > >// Add elements using add method> >list1.add(>1>);> >list1.add(>2>);> >list2.add(>1>);> >list2.add(>2>);> >set.add(list1);> >set.add(list2);> > >// print the set size to understand the> >// internal storage of ArrayList in Set> >System.out.println(set.size());> >}> }>

Androidでブロックされている番号を見つける
>

>

出力:

1>

オブジェクトを保存する前に、HashSet は hashCode() メソッドと equals() メソッドを使用して既存のエントリがあるかどうかを確認します。上の例では、2 つのリストに同じ要素が同じ順序で含まれている場合、2 つのリストは等しいとみなされます。を呼び出すと、 ハッシュコード() 2 つのリストのメソッドを使用すると、それらは等しいため、どちらも同じハッシュを返します。

注記: HashSet は次のことを行います 重複したアイテムを保存しない 、等しい 2 つのオブジェクトを指定すると、最初のオブジェクトのみが保存されます。ここでは list1 です。

HashSet の階層は次のとおりです。

ハッシュセットの内部動作

Set インターフェイスのすべてのクラスは、Map によって内部的にバックアップされます。 HashSet は、オブジェクトを内部に保存するために HashMap を使用します。 HashMap に値を入力するにはキーと値のペアが必要ですが、HashSet では 1 つの値だけを渡していることに疑問に思われるかもしれません。

HashMap 内のストレージ: 実際には、HashSet に挿入した値はマップ オブジェクトへのキーとして機能し、その値として Java は定数変数を使用します。したがって、キーと値のペアでは、すべての値が同じになります。

Java ドキュメントでの HashSet の実装

private transient HashMap map; // Constructor - 1 // All the constructors are internally creating HashMap Object. public HashSet() { // Creating internally backing HashMap object map = new HashMap(); } // Constructor - 2 public HashSet(int initialCapacity) { // Creating internally backing HashMap object map = new HashMap(initialCapacity); } // Dummy value to associate with an Object in Map private static final Object PRESENT = new Object();>

見てみると、 追加() HashSet クラスのメソッド:

public boolean add(E e) { return map.put(e, PRESENT) == null; }>

HashSet クラスの add() メソッドが内部的に 置く() キーとして指定した要素とその値として定数 PRESENT を渡すことにより、HashMap オブジェクトをバッキングするメソッド。 取り除く() メソッドも同様に機能します。これは内部で Map インターフェイスの Remove メソッドを呼び出します。

public boolean remove(Object o) { return map.remove(o) == PRESENT; }>

HashSet は一意のオブジェクトだけでなく、一意のオブジェクトのコレクションも保存します のように 配列リストリンクリスト 、ベクトル、...など

HashSet クラスのコンストラクター

HashSet を作成するには、HashSet クラスのオブジェクトを作成する必要があります。 HashSet クラスは、HashSet の作成を可能にするさまざまなコンストラクターで構成されています。このクラスで使用できるコンストラクターは次のとおりです。

1.ハッシュセット()

このコンストラクターは、デフォルトの初期容量が 16、デフォルトの負荷係数が 0.75 である空の HashSet オブジェクトを構築するために使用されます。 hs という名前の空の HashSet を作成したい場合は、次のように作成できます。

HashSet hs = new HashSet();>

2. HashSet(int 初期容量)

このコンストラクターは、オブジェクト作成時にinitialCapacityが指定された空のHashSetオブジェクトを構築するために使用されます。ここで、デフォルトのloadFactorは0.75のままです。

HashSet hs = new HashSet(int initialCapacity);>

3. HashSet(int 初期容量、浮動小数点ロードファクター)

このコンストラクターは、オブジェクト作成時にinitialCapacityとloadFactorが指定された空のHashSetオブジェクトを構築するために使用されます。

HashSet hs = new HashSet(int initialCapacity, float loadFactor);>

4. ハッシュセット(コレクション)

このコンストラクターは、指定されたコレクションのすべての要素を含む HashSet オブジェクトを構築するために使用されます。つまり、このコンストラクターは、Collection オブジェクトから HashSet オブジェクトへの変換が必要な場合に使用されます。 hs という名前の HashSet を作成したい場合は、次のように作成できます。

HashSet hs = new HashSet(Collection C);>

以下は、上記のトピックの実装です。

ジャワ




// Java program to Demonstrate Working> // of HashSet Class> > // Importing required classes> import> java.util.*;> > // Main class> // HashSetDemo> class> GFG {> > >// Main driver method> >public> static> void> main(String[] args)> >{> > >// Creating an empty HashSet> >HashSet h =>new> HashSet();> > >// Adding elements into HashSet> >// using add() method> >h.add(>'India'>);> >h.add(>'Australia'>);> >h.add(>'South Africa'>);> > >// Adding duplicate elements> >h.add(>'India'>);> > >// Displaying the HashSet> >System.out.println(h);> >System.out.println(>'List contains India or not:'> >+ h.contains(>'India'>));> > >// Removing items from HashSet> >// using remove() method> >h.remove(>'Australia'>);> >System.out.println(>'List after removing Australia:'> >+ h);> > >// Display message> >System.out.println(>'Iterating over list:'>);> > >// Iterating over hashSet items> >Iterator i = h.iterator();> > >// Holds true till there is single element remaining> >while> (i.hasNext())> > >// Iterating over elements> >// using next() method> >System.out.println(i.next());> >}> }>

>

>

出力:

[South Africa, Australia, India] List contains India or not:true List after removing Australia:[South Africa, India] Iterating over list: South Africa India>

HashSet のメソッド

方法

説明

add(そしてそして) 指定された要素が存在しない場合はそれを追加するために使用され、存在する場合は false を返します。
クリア() セットからすべての要素を削除するために使用されます。
contains(オブジェクト o) 要素がセット内に存在する場合に true を返すために使用されます。
削除(オブジェクトo) 要素がセット内に存在する場合、要素を削除するために使用されます。
イテレータ() セット内の要素の反復子を返すために使用されます。
isEmpty() セットが空かどうかを確認するために使用されます。セットの条件が空の場合は true を返し、空でない場合は false を返します。
サイズ() セットのサイズを返すために使用されます。
クローン() セットの浅いコピーを作成するために使用されます。

HashSet に対するさまざまな操作の実行

HashSet で頻繁に使用される操作をいくつか実行する方法を見てみましょう。

1. HashSet への要素の追加

HashSet に要素を追加するには、add() メソッドを使用できます。ただし、挿入オーダーは HashSet には保持されません。重複要素は許可されておらず、重複要素はすべて無視されることに注意してください。

ジャワ




// Java program to Adding Elements to HashSet> > // Importing required classes> import> java.io.*;> import> java.util.*;> > // Main class> // AddingElementsToHashSet> class> GFG {> > >// Method 1> >// Main driver method> >public> static> void> main(String[] args)> >{> >// Creating an empty HashSet of string entities> >HashSet hs =>new> HashSet();> > >// Adding elements using add() method> >hs.add(>'Geek'>);> >hs.add(>'For'>);> >hs.add(>'Geeks'>);> > >// Printing all string el=ntries inside the Set> >System.out.println(>'HashSet elements : '> + hs);> >}> }>

>

>

出力:

HashSet elements : [Geek, For, Geeks]>

2. HashSet 内の要素の削除

値は、remove() メソッドを使用して HashSet から削除できます。

ジャワ

クイックソートアルゴリズム




// Java program Illustrating Removal Of Elements of HashSet> > // Importing required classes> import> java.io.*;> import> java.util.*;> > // Main class> // RemoveElementsOfHashSet> class> GFG {> > >// Main driver method> >public> static> void> main(String[] args)> >{> >// Creating an> >HashSet hs =>new> HashSet();> > >// Adding elements to above Set> >// using add() method> >hs.add(>'Geek'>);> >hs.add(>'For'>);> >hs.add(>'Geeks'>);> >hs.add(>'A'>);> >hs.add(>'B'>);> >hs.add(>'Z'>);> > >// Printing the elements of HashSet elements> >System.out.println(>'Initial HashSet '> + hs);> > >// Removing the element B> >hs.remove(>'B'>);> > >// Printing the updated HashSet elements> >System.out.println(>'After removing element '> + hs);> > >// Returns false if the element is not present> >System.out.println(>'Element AC exists in the Set : '> >+ hs.remove(>'AC'>));> >}> }>

>

>

出力:

Initial HashSet [A, B, Geek, For, Geeks, Z] After removing element [A, Geek, For, Geeks, Z] Element AC exists in the Set : false>

3. HashSet の反復処理

iterator() メソッドを使用して、HashSet の要素を反復処理します。また、最も有名なのは、 for ループが強化されました。

コードブロック

出力

A, B, Geek, For, Geeks, Z, A, B, Geek, For, Geeks, Z,>

HashSet 操作の時間計算量: HashSet の基礎となるデータ構造はハッシュテーブルです。そのため、HashSet の追加、削除、検索 (メソッドを含む) 操作にかかる時間の複雑さを軽減 (平均的または通常の場合) します。 ○(1) 時間。

ハッシュセットのパフォーマンス

HashSet は Abstract Set クラスを拡張して実装します セット 、複製可能、および シリアル化可能 ここで、E はこのセットによって維持される要素のタイプです。 HashSet の直接知られているサブクラスは LinkedHashSet です。

ここで、一定時間のパフォーマンスを維持するために、HashSet の反復処理には、HashSet インスタンスのサイズ (要素の数) とバッキング HashMap インスタンスの容量 (バケットの数) の合計に比例する時間が必要です。したがって、反復パフォーマンスが重要な場合は、初期容量を高すぎないように (または負荷係数を低すぎずに) 設定しないことが非常に重要です。

  • 初期容量: 初期容量とは、ハッシュテーブル (HashSet は内部的にハッシュテーブル データ構造を使用します) が作成されるときのバケットの数を意味します。現在のサイズがいっぱいになると、バケットの数は自動的に増加します。
  • 負荷率: 負荷率は、HashSet の容量が自動的に増加する前に、HashSet がどの程度満たされるかを示す尺度です。ハッシュ テーブル内のエントリの数が負荷係数と現在の容量の積を超えると、ハッシュ テーブルが再ハッシュされ (つまり、内部データ構造が再構築され)、ハッシュ テーブルのバケット数が約 2 倍になります。
 Number of stored elements in the table Load Factor = ----------------------------------------- Size of the hash table>

例: 内部容量が 16 で負荷係数が 0.75 の場合、テーブルに 12 個の要素があると、バケットの数は自動的に増加します。

パフォーマンスへの影響:

負荷率と初期容量は、HashSet 操作のパフォーマンスに影響を与える 2 つの主な要素です。負荷係数 0.75 は、時間と空間の複雑さに関して非常に効果的なパフォーマンスを提供します。負荷係数の値をそれ以上に増やすと、メモリのオーバーヘッドは減少しますが (内部の再構築操作が減少するため)、ハッシュテーブルの追加および検索操作に影響します。再ハッシュ操作を減らすには、初期容量を賢明に選択する必要があります。初期容量がエントリの最大数を負荷係数で割った値より大きい場合、再ハッシュ操作は発生しません。

注記: HashSet の実装は同期されません。つまり、複数のスレッドが同時にハッシュ セットにアクセスし、少なくとも 1 つのスレッドがセットを変更する場合、外部で同期する必要があります。これは通常、セットを自然にカプセル化するオブジェクトを同期することによって実現されます。そのようなオブジェクトが存在しない場合は、Collections.synchronizedSet メソッドを使用してセットをラップする必要があります。これは、次に示すように、セットへの偶発的な非同期アクセスを防ぐために、作成時に行うのが最適です。

Set s = Collections.synchronizedSet(new HashSet(…));

HashSet で使用されるメソッド

1. クラス java.util.AbstractSet から継承されたメソッド

方法

説明

等しい() オブジェクトと HashSet が等しいことを確認し、それらを比較するために使用されます。リストは、順序に関係なく、両方の HashSet に同じ要素が含まれている場合にのみ true を返します。
ハッシュコード() このセットのハッシュ コード値を返します。
すべて削除(コレクション) このメソッドは、セット内に存在するすべての要素をコレクションから削除するために使用されます。呼び出しの結果としてこのセットが変更された場合、このメソッドは true を返します。

2. クラス java.util.AbstractCollection から継承されたメソッド

方法

説明

すべて追加(コレクション)

このメソッドは、言及されたコレクションのすべての要素を既存のセットに追加するために使用されます。

要素は特定の順序に従わずにランダムに追加されます。

すべてを含む(コレクション)

このメソッドは、指定されたコレクションに存在するすべての要素がセットに含まれているかどうかを確認するために使用されます。

このメソッドは、セットにすべての要素が含まれている場合は true を返し、要素のいずれかが欠落している場合は false を返します。

すべて保持(コレクション) このメソッドは、指定されたコレクションで言及されているセットのすべての要素を保持するために使用されます。呼び出しの結果としてこのセットが変更された場合、このメソッドは true を返します。
toArray() このメソッドは、Set と同じ要素の配列を形成するために使用されます。
toString() Java HashSet の toString() メソッドは、HashSet コレクションの要素の文字列表現を返すために使用されます。

3. インターフェース java.util.Collection で宣言されたメソッド

方法

説明

パラレルストリーム() このコレクションをソースとして持つ、並列可能な Stream を返します。
RemoveIf?(述語フィルター) 指定された述語を満たすこのコレクションの要素をすべて削除します。
ストリーム() このコレクションをソースとして含む連続した Stream を返します。
toArray?(IntFunction ジェネレータ) 提供されたジェネレーター関数を使用して、返された配列を割り当て、このコレクション内のすべての要素を含む配列を返します。

4. インターフェース java.lang.Iterable で宣言されたメソッド

方法

説明

forEach?(消費者のアクション) すべての要素が処理されるか、アクションが例外をスローするまで、Iterable の各要素に対して指定されたアクションを実行します。

5. インターフェース java.util.Set で宣言されたメソッド

方法

説明

すべて追加?(コレクション c) 指定されたコレクション内のすべての要素がまだ存在しない場合は、このセットに追加します (オプションの操作)。
すべてを含む?(コレクション c) このセットに指定されたコレクションのすべての要素が含まれている場合は true を返します。
等しい?(オブジェクト o) 指定されたオブジェクトとこのセットが等しいかどうかを比較します。
ハッシュコード() このセットのハッシュ コード値を返します。
すべて削除しますか?(コレクション c) 指定されたコレクションに含まれるすべての要素をこのセットから削除します (オプションの操作)。
すべて保持?(コレクション c) 指定されたコレクションに含まれるこのセット内の要素のみを保持します (オプションの操作)。
toArray() このセット内のすべての要素を含む配列を返します。
toArray?(T[] a) このセット内のすべての要素を含む配列を返します。返される配列のランタイム型は、指定された配列のランタイム型です。

Java の HashSet に関する FAQ

Q1. JavaのHashSetとは何ですか?

答え:

HashSet はクラスの一種で、AbstractSet を拡張し、Set インターフェイスを実装します。

Q2.なぜHashSetが使われるのでしょうか?

答え:

HashSet は、データの重複を避け、高速な方法で値を見つけるために使用されます。

Q3. HashSet と HashMap の違い。

答え:

基礎

ハッシュセット

ハッシュマップ

実装 HashSet は Set インターフェイスを実装します。 HashMap は、storesMap インターフェイスを実装します。
重複 HashSet では重複した値は許可されません。 HashMap はキーと値のペアを保存し、重複したキーを許可しません。キーが重複している場合は、古いキーが新しい値に置き換えられます。
オブジェクト格納時のオブジェクト数 HashSet にはオブジェクト add(Object o) が 1 つだけ必要です。 HashMap には、HashMap オブジェクトに要素を追加するために 2 つのオブジェクト put(K key, V Value) が必要です。
ダミー値 HashSet は内部で HashMap を使用して要素を追加します。 HashSet では、add(Object) メソッドで渡された引数がキー K として機能します。Java は、add(Object) メソッドで渡された各値に内部でダミー値を関連付けます。 HashMap にはダミー値の概念がありません。
メカニズムの保存または追加 HashSet は内部で HashMap オブジェクトを使用してオブジェクトを保存または追加します。 HashMap は内部でハッシュを使用してオブジェクトを保存または追加します
もっと早く HashSet は HashMap よりも低速です。 HashMap は HashSet よりも高速です。
挿入 HashSet は、データの追加または保存に add() メソッドを使用します。 HashMap はデータの保存に put() メソッドを使用します。
HashSet はセットです。 {1、2、3、4、5、6、7}。 HashMap は、キー -> 値のペア (キーと値) マップです。 {a -> 1、b -> 2、c -> 2、d -> 1}。

Q4. Java における HashSet と TreeSet の違い。

答え:

基礎

ハッシュセット

ツリーセット

スピードと内部実装、スローアクション 検索、挿入、削除などの操作用。これらの操作には平均して一定の時間がかかります。 HashSet は TreeSet より高速です。 HashSet はハッシュ テーブルを使用して実装されます。 TreeSet は、検索、挿入、削除に O(Log n) を要しますが、これは HashSet よりも高くなります。ただし、TreeSet はソートされたデータを保持します。また、higher() (最も上位の要素を返す)、floor()、ceiling() などの操作もサポートしています。これらの操作も TreeSet では O(Log n) であり、HashSet ではサポートされていません。 TreeSet は、自己分散二分探索ツリー (赤黒ツリー) を使用して実装されます。 TreeSet は Java の TreeMap によってサポートされています。
注文 HashSet 内の要素は順序付けされていません。 TreeSet は、Java の Comparable メソッドまたは Comparator メソッドで定義された Sorted 順序でオブジェクトを維持します。 TreeSet 要素はデフォルトで昇順に並べ替えられます。 first()、last()、headSet()、tailSet() などの順序付きセットを処理するためのメソッドがいくつか提供されています。
ヌルオブジェクト HashSet では null オブジェクトが許可されます。 TreeSet は null オブジェクトを許可せず、NullPointerException をスローします。その理由は、TreeSet がキーを比較するために CompareTo() メソッドを使用し、compareTo() が java.lang.NullPointerException をスローするためです。
比較 HashSet は、equals() メソッドを使用して Set 内の 2 つのオブジェクトを比較し、重複を検出します。 TreeSet は同じ目的で CompareTo() メソッドを使用します。 equals() と CompareTo() が一貫していない場合、つまり、2 つの等しいオブジェクトに対して、equal は true を返し、compareTo() は 0 を返す必要があります。その場合、Set インターフェイスのコントラクトが破棄され、TreeSet などの Set 実装での重複が許可されます。