私はJavaコレクションフレームワークを学んでいて、適度な理解を得ました。今、少し先に進むと、HashMap
、HashSet
、Hashtable
。
HashMap
のJavadocは次のように述べています。
Mapインターフェイスのハッシュテーブルベースの実装。この実装は、すべてのオプションのマップ操作を提供し、null値とnullキーを許可します。
HashSet
のJavadocは次のように述べています。
このクラスは、ハッシュテーブル(実際にはHashMapインスタンス)に基づくSetインターフェースを実装します。セットの反復順序については保証されません。特に、順序が長期にわたって一定であることを保証するものではありません。
Hashtable
のJavadocは次のように述べています。
このクラスは、キーを値にマップするハッシュテーブルを実装します。 null以外のオブジェクトは、キーまたは値として使用できます。
それらすべてがhash table
を実装していると混乱します。 ハッシュテーブルのコンセプトを実装していますか?
これらはすべて関連しているようですが、完全には理解できません。
誰かがこの概念を単純な言語で理解するのを手伝ってくれる?.
JavaのSet
およびMap
インターフェースは、2つの非常に異なるコレクション型を指定します。 Set
は、それがどのように聞こえるかということです。他の構造を持たない、別個の(等しくない)オブジェクトのコレクションです。 Map
は、概念的には、オブジェクトのセット(キー)からオブジェクトのコレクション(値)へのマッピングです。 Hashtable
とHashMap
はどちらもMap
を実装し、HashSet
はSet
を実装し、すべてセットに含まれるキー/オブジェクトにハッシュコードを使用しますパフォーマンスを向上させます。
Hashtable
およびHashMap
Hashtable
はレガシークラスであり、ほとんどの場合HashMap
を優先して回避する必要があります。 Hashtable
のほとんどのメソッドが同期され、個々のメソッド呼び出しがスレッドセーフになることを除いて、それらは基本的に同じことを行います。1 複数のスレッドとHashMap
を使用している場合は、独自の同期または他のスレッドセーフティメカニズムを提供する必要があります。
Hashtable
の問題は、各メソッド呼び出しの同期(重要ではない操作)が通常間違っていることです。まったく同期する必要がないか、アプリケーションロジックの観点からは、複数のメソッド呼び出しにまたがるトランザクションを介して同期する必要があります。既存のコードを壊さずにHashtable
からメソッドレベルの同期を単純に削除することは不可能だったので、コレクションフレームワークの作成者は新しいクラスを考え出す必要がありました。したがって、HashMap
です。 Map
の一種であることが明らかになるため、この名前の方が適しています。
ああ、メソッドレベルの同期が必要な場合でも、Hashtable
を使用しないでください。代わりに、 Collections.synchronizedMap()
を呼び出して、マップを同期されたマップに変換できます。または、ConcurrentHashMap
を使用することもできます。これは the docs : "Hashtable
と同じ機能仕様に従いますが、より優れたパフォーマンスと追加機能( putIfAbsent()
)。
1HashMap
がnull
の値とキーをサポートするなど、他の違いがあります(それほど重要ではないと思います)。
HashSet
機能面では、HashSet
はHashMap
とは関係ありません。たまたま内部でHashMap
を使用してSet
機能を実装しています。何らかの理由で、コレクションフレームワークの開発者は、この内部実装の詳細をクラスのパブリック仕様の一部にすることをお勧めします。 (これは私の見解ではエラーでした。)
Hashtableは、Javaにジェネリックが含まれる前に作成された古いクラスでした。下位互換性のためにまだ残っています。代わりにHashMapを使用してください。
キーを値にマップする必要がない場合は、HashSetを使用します。ハッシュテーブルと同じアルゴリズムに基づいて構築されていますが、根本的に異なる目的で使用されています。
HashMapとHashTableはどちらもMapインターフェースを継承しています。動作とプロパティはほとんど同じですが、主な違いは次のとおりです。
1.ハッシュマップはキーと値のペアの順序付けられていないマップです。ハッシュマップ内にnullのキーまたは値のペアを含めることができます。また、ハッシュマップは非同期です(つまり、スレッドセーフではないため、複数のスレッドが同時にアクセスして変更できます)。ただし、外部でハッシュマップをスレッドセーフにすることができます。したがって、同期の問題を考慮しない場合は、ハッシュマップが推奨されます。
2.HashTable:-同期されたhashMap(つまり、スレッドセーフハッシュマップ)。ただし、この場合のキーと値のペアがnullになることはありません。Hashtableでは、キーとして使用されるオブジェクトと、目的の値を指定します。そのキーに関連付けます。次に、キーがハッシュされ、結果のハッシュコードが、値がテーブル内に格納されるインデックスとして使用されます
3.HashSet:-ハッシュセットはセットインターフェイスを継承し、最終的にはハッシュテーブルにも基づいています(または、ハッシュマップにのみ深く関連していると言えます)。ただし、この場合、キーと値のペアは常に一意であり、重複する値は許可されません。ただしnullキー値が許可されます。オブジェクトはハッシュコードに基づいて挿入されます。
結論として、3つのコレクションすべてがMapインターフェースに接続されていると言えます。