CodeGym /Java Blog /ランダム /Java ハッシュテーブル
John Squirrels
レベル 41
San Francisco

Java ハッシュテーブル

ランダム グループに公開済み
Java Hashtableクラスは、Java Collection Framework の最も古いメンバーの 1 つです。数学的ハッシュ テーブル データ構造の実装です。Java のハッシュテーブルには、キーと値のペアが格納されるバケットが内部に含まれています。Hashtable はHashMapによく似ています。それらの最も重要な違いは、Hashtableは同期されますが、HashMapは同期されないことです。

データ構造としてのハッシュテーブル

ハッシュテーブルは、データが配列形式で格納されるデータ構造です。すべてのデータ値には一意のキー値があります。キーがわかっていれば、必要なデータに非常に高速にアクセスできます。したがって、挿入および検索操作はデータ サイズに関係なく高速になります。ハッシュ テーブルは、データを保持する配列と、要素が配置されるインデックスを生成するためのハッシュで構成されます。ハッシュ化とは何ですか? これは、オブジェクトを文字のセット (コード) にマッピングするルールです。通常、この種の関数は大きなデータを小さな整数値に変換します。ハッシュ関数は異なる場合がありますが、それらはすべて特定のプロパティを送信します。
  • 特定のオブジェクトには特定のハッシュ コードがあります。
  • 2 つの等しいオブジェクトは同じハッシュ コードを持ちます。逆は当てはまりません。
  • 2 つのハッシュ コードが異なる場合、オブジェクトは明らかに等しくありません。
  • 異なるオブジェクトが同じハッシュ コードを持つ場合があります。この非常にまれなイベントは衝突と呼ばれます。優れたハッシュ関数により、衝突の可能性が最小限に抑えられます。
オブジェクトにハッシュ関数を適用した結果は、hashCodeを呼び出します。

Javaのハッシュテーブル

Hashtableクラスは、ハッシュ テーブル データ構造の実装です。このコレクションは Java Collection Framework よりも前に作成されましたが、後に Java Collection Framework に組み込まれました。すべての「初期」コレクション (Java 1.0 以降) と同様に、ハッシュテーブルは同期されます (ほぼすべてのメソッドが同期済みとしてマークされます)。この要因により、hashtable には重大なパフォーマンスの問題が発生します。したがって、Java 1.2 以降では、同期が欠如しているため、ほとんどの場合、 Mapインターフェースの他の実装を使用することが推奨されます。通常、HashMap が最も適切な代替品です。したがって、クラスHashtable<K,V>キーと値で構成されます。ハッシュの原理に基づいてキーを保存します。キーと値のペアは「バケット」に保存されます。バケットは一緒になって、一種の内部配列である「テーブル」を構築します。ハッシュテーブルは、キーのハッシュコードを使用して、キーと値のペアをマッピングするバケットを決定します。ハッシュ関数を使用すると、キーのハッシュコードからバケットの場所を取得できます。この関数は、オブジェクトの整数を返します。上で述べたように、2 つの等しいオブジェクトは同じハッシュコードを持ちますが、2 つの等しくないオブジェクトは必ずしも異なるハッシュコードを持つとは限りません。ハッシュテーブルに入れられた異なるオブジェクトは、同じハッシュ コードを持つ可能性があります。この問題 (衝突) を解決するには、ハッシュテーブルでリストの配列が使用されます。単一のバケットにマップされたペアはリストに格納され、このリスト参照は配列インデックスに格納されます。

ハッシュテーブル Java コンストラクター

  • Hashtable()、デフォルトのコンストラクター。空のハッシュテーブルが作成されます。(デフォルトの初期容量 = 11、負荷率 = 0.75)。
  • Hashtable(int size) は、指定されたサイズのハッシュテーブルを構築します。
  • Hashtable(int size, float fillRatio) は、指定されたサイズと充填率のハッシュ テーブルを作成します。
  • Hashtable(Map m) は、指定された Map と同じマッピングを持つハッシュテーブルを作成します。

ハッシュテーブル宣言

Hashtable Java クラスは、Map Cloneable およびSerializableインターフェイスを実装します。Dictionaryクラスを拡張します。

Hashtable.java
public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable
Kは、マップによって維持されるキーのタイプです。 V はマップされた値のタイプです。例:

Hashtable<Student, Integer> myHTable = new Hashtable<>();

ハッシュテーブルJavaをインポートする方法

Java ハッシュテーブルはjava.utilパッケージ内にあります。したがって、import java.util.Hashtable を使用します。あなたのコードに。通常、これについては IDE からヒントが得られます。

ハッシュテーブルの主な操作

ハッシュテーブルの主な操作は、コレクションの取得、コレクションへの挿入、コレクションからの削除です。ここでの 3 つの操作は次のとおりです。
  • Object get(Object key) は、指定されたキーを持つオブジェクトの値を返します。そのようなキーが見つからない場合は null を返します。
  • Object put(Object key, Object value) は、指定されたキーを指定された値にマップします。キーも値も null にすることはできません。
  • Object Remove(Object key) は、ハッシュテーブルからエントリ (キーと対応する値) を削除します。
その他の重要な操作:
  • int size() は、ハッシュ テーブル内のエントリの量を返します。
  • boolean contains(Object value) は、指定された値がハッシュ テーブルにあるかどうかを確認します。そうである場合、メソッドは true を返し、そうでない場合は false を返します。
  • boolean containsValue(Object value) は、指定された値がハッシュ テーブルにあるかどうかを確認します。そうである場合、メソッドは true を返し、そうでない場合は false を返します。
  • void clear() は、ハッシュテーブルからすべてのエントリを削除します。
  • boolean containsKey(Object key) は、指定されたキーがハッシュ テーブルに存在する場合は true を返し、それ以外の場合は false を返します。
  • boolean isEmpty() は、ハッシュテーブルが空の場合は true を返し、少なくとも 1 つのキーが含まれている場合は false を返します。
  • void rehash() は、ハッシュテーブルのサイズを増やし、そのすべてのキーを再ハッシュします。

ハッシュ テーブルの実装、Java コード:

Studentクラスを作成しましょう。

import java.util.Date;
public class Student {
   String surname;
   String name;
   String secondName;
   Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases

   public Student(String surname, String name, String secondName, Date birthday ){
       this.surname = surname;
       this.name = name;
       this.secondName = secondName;
       this.birthday = birthday == null ? 0 : birthday.getTime();
   }

   @Override
   public int hashCode(){
       //TODO: check for nulls
       return (surname + name + secondName + birthday).hashCode();
   }
   @Override
   public boolean equals(Object other_) {
       Student other = (Student)other_;
       return (surname == null || surname.equals(other.surname) )
               && (name == null || name.equals(other.name))
               && (secondName == null || secondName.equals(other.secondName))
               && (birthday == null || birthday.equals(other.birthday));
   }
}
Javaハッシュテーブルの例を次に示します。Studentクラスの 2 つのオブジェクトをハッシュテーブルに配置し、いくつかを削除していくつかのパラメーターを確認してみましょう。

public class HashTableExample {
   public static void main(String[] args) {
 
       Hashtable<Student, Integer> myHTable = new Hashtable<>();
       Student sarah1 = new Student("Sarah","Connor", "Jane", null);
       Student john = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
       myHTable.put(john,1);
       myHTable.put(sarah1,0);
       System.out.println(myHTable.get(john));
       System.out.println(myHTable.isEmpty());
       System.out.println(myHTable.size());
       System.out.println(myHTable.contains(1));
       myHTable.remove(john);
       System.out.println(myHTable.contains(0));
       System.out.println(myHTable.contains(1));
       System.out.println(myHTable.containsKey(sarah1));
   }
}
プログラムを実行した結果は次のようになります。

1
false
2
true
true
false
true

ハッシュマップとハッシュテーブル

  • Hashtable は Java の HashMap に似ています。最も大きな違いは、Hashtable は同期されるのに対し、HashMap は同期されないことです。したがって、Hashtable は同期のために HashMap よりも遅くなります。
  • 同期の問題を除いて、Hashtable では値またはキーとして null を使用することはできません。HashMap では、1 つの null キーと複数の null 値が許可されます。
  • Hashtable は Dictionary クラスを継承し、HashMap は AbstractMap クラスを継承します。
  • HashMap は Iterator によって走査されます。Hashtable は Iterator だけでなく Enumerator でも走査できます。

Java ハッシュテーブルの例 (ハッシュテーブルと HashMap の null キー)

これは、 HashMapHashtableでキーと値として使用される null を示すフラグメント コードです。

// Null key Java hashtable example and hashmap example  

try{
      System.out.println("Hashtable");
      Hashtable hashTable = new Hashtable();
      hashTable.put(null, new Object());
    }catch(Exception ex){
      ex.printStackTrace();
    }
    System.out.println("HashMap");
    HashMap hashMap = new HashMap();
    hashMap.put(null, new Object());
    System.out.println("as you see no exceptions with null key in HashMap");
  }
このフラグメントを含むプログラムを実行した結果は次のようになります。

java.lang.NullPointerException
	at java.base/java.util.Hashtable.put(Hashtable.java:480)
	at Character.main(Character.java:58)
HashMap
as you see no exceptions with null key in HashMap

結論

実際のプロジェクトで Hashtable を使用することはあまりありませんが、古いプロジェクトではこのデータ構造を満たすのは簡単です。いずれにせよ、少なくともインタビューのためには、Java のデータ構造が何なのか、そしてそれらがどのように機能するのかを理解することが重要です。通常、HashMap オブジェクトは類似性があるため、Hashtable の代わりに使用されます。HashMap はより効果的であり (同期されません)、キーとして null を使用できます。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION