ハッシュテーブルクラス
Hashtable は Map インターフェイスを継承し、キーと値のマッピングのハッシュ テーブルを実装します。 null 以外の任意のオブジェクトをキーまたは値として使用できます。
データを追加するには put(key,value) を使用し、データを削除するには get(key) を使用します。これら 2 つの基本操作の時間コストは一定です。
Hashtable は、初期容量と負荷率という 2 つのパラメーターを通じてパフォーマンスを調整します。通常、デフォルトの負荷係数 0.75 を使用すると、時間と空間のバランスがより良くなります。負荷率を増やすとスペースを節約できますが、それに対応する検索時間が増加し、get や put などの操作に影響します。
Hashtable を使用する簡単な例は次のとおりです。Hashtable に 1、2、および 3 を入力します。これらのキーはそれぞれ「one」、「two」、「three」です。
ハッシュテーブル番号 = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“2”, new Integer(2));
numbers.put(“three”, new Integer(3));
2 などの数値を取得するには、対応するキーを使用します。
整数 n = (整数)numbers.get(“two”);
System.out.println(“two = ” + n);
キーとして使用されるオブジェクトはハッシュ関数を計算することによって対応する値の位置を決定するため、キーとして使用されるオブジェクトはすべて hashCode メソッドと等しいメソッドを実装する必要があります。 hashCode メソッドと equals メソッドは、ルート クラス Object を継承します。カスタム クラスをキーとして使用する場合、ハッシュ関数の定義に従って、2 つのオブジェクトが同じである場合、つまり obj1.equals( obj2)=true の場合、それらのハッシュコードは同じである必要がありますが、2 つの異なるオブジェクトのハッシュコードが同じである場合、この現象は競合と呼ばれます。ハッシュ テーブルの操作にかかる時間のオーバーヘッドが増加するため、ハッシュ テーブルの操作を高速化するために、明確に定義された hashCode() メソッドを定義するようにしてください。
同じオブジェクトに異なる hashCode がある場合、ハッシュ テーブルの操作で予期しない結果が生じます (期待された get メソッドが null を返す)。この問題を回避するには、1 つのことだけを覚えておく必要があります。それは、equals メソッドと hashCode メソッドを同時にオーバーライドすることです。そのうちの 1 つだけを書かないでください。ハッシュテーブルは同期です。
ハッシュマップクラス
HashMap は Hashtable に似ていますが、HashMap が非同期で null、つまり null 値と null キーを許可する点が異なります。ただし、HashMap をコレクションとして扱う場合 (values() メソッドはコレクションを返すことができます)、その反復サブオペレーションの時間オーバーヘッドは HashMap の容量に比例します。したがって、反復操作のパフォーマンスが非常に重要な場合は、HashMap の初期容量を高く設定しすぎたり、負荷率を低く設定しすぎたりしないでください。
WeakHashMap クラス
WeakHashMap は、キーへの「弱参照」を実装する改良された HashMap で、キーが外部から参照されなくなった場合、そのキーは GC によってリサイクルできます。
HashSet については Set の説明を参照してください。
Set は、重複する要素を含まない Collection です。つまり、任意の 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 です。
セット s= 新しい HashSet(17);
HashSet には、負荷係数と呼ばれる「調整パラメータ」もあります。 HashSet のスペース使用量が非常に気になる場合は、HashSet のテキストを読んで詳細を確認してください。それ以外の場合は、デフォルト値をそのまま使用します。デフォルトの負荷係数を受け入れても、初期容量を指定したい場合は、セットが拡張すると予想される容量の約 2 倍の数値を選択します。推測が的外れであれば、データが大きくなったり、わずかなスペースが無駄になったりする可能性があります。しかし、大きな問題はありません。正しいサイズに最適な値がわかっている場合は、それを使用します。わからない場合は、古い値を使用するか、偶数の値を使用します。それは実際にはあまり重要ではありません。これらは HashSet をわずかに改善するだけです。
TreeSet には調整パラメータがありません。クローンに加えて、HashSet と TreeSet には、それぞれのインターフェイス (Set と TreeSet) で必要な操作のみがあり、他の操作はありません。