ホームページ  >  記事  >  Java  >  JavaのHashMap、Hashtable、HashSetの違い

JavaのHashMap、Hashtable、HashSetの違い

高洛峰
高洛峰オリジナル
2017-01-19 10:26:531682ブラウズ

Hashtableクラス
HashtableはMapインターフェースを継承し、キーと値のマッピングのハッシュテーブルを実装します。 null 以外の任意のオブジェクトをキーまたは値として使用できます。

データを追加するには put(key,value) を使用し、データを削除するには get(key) を使用します。これら 2 つの基本操作の時間コストは一定です。

ハッシュテーブルは、初期容量と負荷率という 2 つのパラメーターを通じてパフォーマンスを調整します。通常、デフォルトの負荷係数 0.75 を使用すると、時間とスペースのバランスがより良くなります。負荷率を増やすとスペースを節約できますが、それに対応する検索時間が増加し、get や put などの操作に影響します。

Hashtable を使用する簡単な例は次のとおりです。Hashtable に 1、2、3 を入力します。それぞれのキーは「one」、「two」、「three」です。
ハッシュテーブルの番号 = new Hashtable();
numbers.put(“1”, new Integer(1));
numbers.put(“three”, new Integer(3)); 2 などの数値を取得するには、対応するキーを使用します:
Integer n = (Integer)numbers.get(“two”);

オブジェクトからキーが計算されるとき、そのハッシュ関数は対応する値の位置を決定するために使用されるため、キーとして使用されるオブジェクトはすべて hashCode メソッドと等しいメソッドを実装する必要があります。 hashCode メソッドと equals メソッドは、ルート クラス Object を継承します。カスタム クラスをキーとして使用する場合、ハッシュ関数の定義に従って、2 つのオブジェクトが同じである場合、つまり obj1.equals( obj2)=true の場合、それらのハッシュコードは同じである必要がありますが、2 つの異なるオブジェクトのハッシュコードが同じである場合、この現象は競合と呼ばれます。ハッシュ テーブルの操作にかかる時間のオーバーヘッドが増加するため、ハッシュ テーブルの操作を高速化するために、明確に定義された hashCode() メソッドを定義するようにしてください。

同じオブジェクトに異なる hashCode がある場合、ハッシュ テーブルの操作で予期しない結果が生じます (予想される get メソッドが null を返す)。この問題を回避するには、1 つのことだけを覚えておく必要があります。それは、equals メソッドと hashCode をオーバーライドすることです。メソッドを 1 つだけ書くのではなく、同時に実行します。ハッシュテーブルは同期です。

HashMap クラス

HashMap は Hashtable に似ていますが、HashMap が非同期で null、つまり null 値と null キーを許可する点が異なります。ただし、HashMap をコレクションとして扱う場合 (values() メソッドはコレクションを返すことができます)、その反復サブオペレーションの時間オーバーヘッドは HashMap の容量に比例します。したがって、反復操作のパフォーマンスが非常に重要な場合は、HashMap の初期容量を高く設定しすぎたり、負荷率を低く設定しすぎたりしないでください。


WeakHashMap クラス
WeakHashMap は、キーへの「弱参照」を実装する改良された HashMap です。キーが外部から参照されなくなった場合、そのキーは GC によってリサイクルできます。

HashSet Set の説明を参照してください。
Set は、繰り返しの要素を含まないコレクションです。つまり、任意の 2 つの要素 e1 と e2 に e1.equals(e2)=false があり、Set には最大 1 つの null 要素があります。

Set のコンストラクターには、渡された Collection パラメーターに重複した要素を含めることができないという制約があります。

注意: 可変オブジェクトは注意して扱う必要があります。 Set 内の可変要素の状態が変化して Object.equals(Object)=true になると、いくつかの問題が発生します。

2 つの一般的な Set 実装は、HashSet と TreeSet です。どちらを使用するかを決定するのは非常に簡単です。 HashSet ははるかに高速です (ほとんどの操作のログ時間と比較して定数時間) が、順序の保証はありません。 SortedSet で操作を使用する必要がある場合、または順番に反復することが重要な場合は、TreeSet を使用してください。それ以外の場合は、HashSet を使用します。ほとんどの場合、HashSet を使用しないのはかなりの賭けです。

HashSet について留意すべき点の 1 つは、反復はエントリ数と容量の合計に関して線形であるということです。したがって、反復パフォーマンスが重要な場合は、適切な初期容量を慎重に選択する必要があります。大きすぎる容量を選択すると、スペースと時間の両方が無駄になります。デフォルトの初期容量は 101 ですが、これは通常、必要以上に大きくなります。初期容量は int コンストラクターを使用して指定できます。割り当てられる HashSet の初期容量は 17 です:

Set s= new HashSet(17);

HashSet には負荷係数と呼ばれる「調整パラメータ」もあります。 HashSet のスペース使用量が非常に気になる場合は、HashSet のテキストを読んで詳細を確認してください。それ以外の場合は、デフォルト値をそのまま使用します。デフォルトの負荷係数を受け入れても、初期容量を指定したい場合は、セットが増加すると予想される容量の約 2 倍の数値を選択します。推測が的外れであれば、データが大きくなったり、わずかなスペースが無駄になったりする可能性があります。しかし、大きな問題はありません。正しいサイズに最適な値がわかっている場合は、それを使用します。わからない場合は、古い値を使用するか、偶数の値を使用します。それは実際にはあまり重要ではありません。これらは HashSet をわずかに改善するだけです。

TreeSet には調整するパラメータがありません。クローンに加えて、HashSet と TreeSet には、それぞれのインターフェイス (Set と TreeSet) で必要な操作のみがあり、他の操作はありません。


Java の HashMap、Hashtable、HashSet の違いに関するその他の記事については、PHP 中国語 Web サイトに注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。