web-dev-qa-db-ja.com

Hashtable、HashMap、HashSet、Javaコレクションフレームワークのハッシュテーブルコンセプト

私はJavaコレクションフレームワークを学んでいて、適度な理解を得ました。今、少し先に進むと、HashMapHashSetHashtable

HashMapのJavadocは次のように述べています。

Mapインターフェイスのハッシュテーブルベースの実装。この実装は、すべてのオプションのマップ操作を提供し、null値とnullキーを許可します。

HashSetのJavadocは次のように述べています。

このクラスは、ハッシュテーブル(実際にはHashMapインスタンス)に基づくSetインターフェースを実装します。セットの反復順序については保証されません。特に、順序が長期にわたって一定であることを保証するものではありません。

HashtableのJavadocは次のように述べています。

このクラスは、キーを値にマップするハッシュテーブルを実装します。 null以外のオブジェクトは、キーまたは値として使用できます。

それらすべてがhash tableを実装していると混乱します。 ハッシュテーブルコンセプトを実装していますか?

これらはすべて関連しているようですが、完全には理解できません。

誰かがこの概念を単純な言語で理解するのを手伝ってくれる?.

17
CuriousMind

JavaのSetおよびMapインターフェースは、2つの非常に異なるコレクション型を指定します。 Setは、それがどのように聞こえるかということです。他の構造を持たない、別個の(等しくない)オブジェクトのコレクションです。 Mapは、概念的には、オブジェクトのセット(キー)からオブジェクトのコレクション(値)へのマッピングです。 HashtableHashMapはどちらもMapを実装し、HashSetSetを実装し、すべてセットに含まれるキー/オブジェクトにハッシュコードを使用しますパフォーマンスを向上させます。

HashtableおよびHashMap

Hashtableはレガシークラスであり、ほとんどの場合HashMapを優先して回避する必要があります。 Hashtableのほとんどのメソッドが同期され、個々のメソッド呼び出しがスレッドセーフになることを除いて、それらは基本的に同じことを行います。1 複数のスレッドとHashMapを使用している場合は、独自の同期または他のスレッドセーフティメカニズムを提供する必要があります。

Hashtableの問題は、各メソッド呼び出しの同期(重要ではない操作)が通常間違っていることです。まったく同期する必要がないか、アプリケーションロジックの観点からは、複数のメソッド呼び出しにまたがるトランザクションを介して同期する必要があります。既存のコードを壊さずにHashtableからメソッドレベルの同期を単純に削除することは不可能だったので、コレクションフレームワークの作成者は新しいクラスを考え出す必要がありました。したがって、HashMapです。 Mapの一種であることが明らかになるため、この名前の方が適しています。

ああ、メソッドレベルの同期が必要な場合でも、Hashtableを使用しないでください。代わりに、 Collections.synchronizedMap() を呼び出して、マップを同期されたマップに変換できます。または、ConcurrentHashMapを使用することもできます。これは the docs : "Hashtableと同じ機能仕様に従いますが、より優れたパフォーマンスと追加機能( putIfAbsent())。

1HashMapnullの値とキーをサポートするなど、他の違いがあります(それほど重要ではないと思います)。

HashSet

機能面では、HashSetHashMapとは関係ありません。たまたま内部でHashMapを使用してSet機能を実装しています。何らかの理由で、コレクションフレームワークの開発者は、この内部実装の詳細をクラスのパブリック仕様の一部にすることをお勧めします。 (これは私の見解ではエラーでした。)

35
Ted Hopp

Hashtableは、Javaにジェネリックが含まれる前に作成された古いクラスでした。下位互換性のためにまだ残っています。代わりにHashMapを使用してください。

キーを値にマップする必要がない場合は、HashSetを使用します。ハッシュテーブルと同じアルゴリズムに基づいて構築されていますが、根本的に異なる目的で使用されています。

3
Beefster

HashMapとHashTableはどちらもMapインターフェースを継承しています。動作とプロパティはほとんど同じですが、主な違いは次のとおりです。

1.ハッシュマップはキーと値のペアの順序付けられていないマップです。ハッシュマップ内にnullのキーまたは値のペアを含めることができます。また、ハッシュマップは非同期です(つまり、スレッドセーフではないため、複数のスレッドが同時にアクセスして変更できます)。ただし、外部でハッシュマップをスレッドセーフにすることができます。したがって、同期の問題を考慮しない場合は、ハッシュマップが推奨されます。

2.HashTable:-同期されたhashMap(つまり、スレッドセーフハッシュマップ)。ただし、この場合のキーと値のペアがnullになることはありません。Hashtableでは、キーとして使用されるオブジェクトと、目的の値を指定します。そのキーに関連付けます。次に、キーがハッシュされ、結果のハッシュコードが、値がテーブル内に格納されるインデックスとして使用されます

3.HashSet:-ハッシュセットはセットインターフェイスを継承し、最終的にはハッシュテーブルにも基づいています(または、ハッシュマップにのみ深く関連していると言えます)。ただし、この場合、キーと値のペアは常に一意であり、重複する値は許可されません。ただしnullキー値が許可されます。オブジェクトはハッシュコードに基づいて挿入されます。

結論として、3つのコレクションすべてがMapインターフェースに接続されていると言えます。

2
P.sharma