Java のオブジェクトには次のメソッドがあります。
パブリックネイティブ int ハッシュコード();
(1) hashcode()メソッドの役割
hashcode() メソッドは、主に基于散列的集合
などと一緒に使用されますHashSet、HashMap、HashTable
。
コレクションに新しいオブジェクトを追加する必要がある場合、最初にこのオブジェクトの hashcode() メソッドを呼び出して、対応するハッシュコード値を取得します。実際、ハッシュマップには、格納されているオブジェクトのハッシュコード値を格納するテーブルが存在します。テーブルにそのようなハッシュコード値が存在しない場合は、直接格納されます。存在する場合は、equals メソッドが呼び出され、新しい要素と比較されます。
(2) イコールとハッシュコードの関係
等しいが true の場合、ハッシュコードは等しい必要があります。
等しいが false の場合、ハッシュコードは必ずしも等しくないわけではありません。
ハッシュコード値が等しい場合、イコールは必ずしも等しいわけではありません。
ハッシュコード値が等しくない場合、等しいものは等しくない必要があります。
注:equals メソッドを書き換えるときは、必ず hashcode メソッドを書き換えてください。
(3)百度百科事典
hashcode メソッドはオブジェクトの を返します哈希码值
。このメソッドは、java.util.Hashtable によって提供されるハッシュ テーブルなどに比べていくつかの利点を提供するためにサポートされています。
hashCode の一般的な規約は、
Java アプリケーションの実行中、在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数
オブジェクトの等価比較で使用される情報が変更されないという条件です。この整数は、アプリケーションの 1 つの実行から同じアプリケーションの別の実行まで一貫している必要はありません。
equals(Object) メソッドに従って 2 つのオブジェクトが等しい場合、2 つのオブジェクトのそれぞれに対して hashCode メソッドを呼び出すと、同じ整数の結果が生成される必要があります。
2 つのオブジェクトが、equals(java.lang.Object) メソッドに従って等しくない場合、いずれかのオブジェクトで hashCode メソッドを呼び出すと、異なる整数の結果が生成される必要はありません。ただし、プログラマは、等しくないオブジェクトに対して異なる整数の結果を生成すると、ハッシュ テーブルのパフォーマンスが向上する可能性があることに注意する必要があります。
実際、Object クラスによって定義された hashCode メソッドは、オブジェクトごとに異なる整数を返します。(これは通常、オブジェクトの内部アドレスを整数に変換することによって実現されますが、JavaTM プログラミング言語ではこの実装トリックは必要ありません。)
equals メソッドがオーバーライドされる場合、多くの場合、等しいオブジェクトは等しいハッシュ コードを持つ必要があるという hashCode メソッドの一般規約を維持するために、hashCode メソッドをオーバーライドする必要があります。
(4) 小白氏の説明
1. ハッシュコードは検索に使用されます。データ構造を学習したことがある場合は、検索とソートの章で、たとえば、メモリ内に 0 1 2 3 4 5 6 7 のような位置があり、クラスがあることを知っているはずです。このクラスには ID と呼ばれるフィールドがあります。このクラスを上記の 8 つの位置のいずれかに格納したいと考えて
い
ます
。
しかし、ハッシュコードを使用すると、効率が大幅に向上します。
クラスには ID というフィールドがあり、ハッシュコードを ID% 8 として定義し、剰余が得られる位置にクラスを格納します。たとえば、ID が 9 で、9 を 8 で割った余りが 1 の場合、クラスを 1 の位置に格納します。ID が 13 で、余りが 5 の場合、クラスを 5 の位置に格納します。このようにすると、今後このクラスを検索するときに、ID を 8 で割った余りを求めることで、保存場所を直接見つけることができます。
2. しかし、2 つのクラスが同じハッシュコードを持つ場合はどうなるでしょうか (上記のクラスの ID は一意ではないと仮定します)、たとえば、9 を 8 で割った余り、17 を 8 で割った余りが 1 である場合、これは合法でしょうか? 答えは、「はい」です。では、どのように判断すればよいのでしょうか?このとき、等しいものを定義する必要があります。
つまり、最初にハッシュコードを通じて 2 つのクラスがバケットに格納されているかどうかを判断しますが、このバケットには多数のクラスが存在する可能性があるため、このバケット内で必要なクラスを見つけるには、equals を使用する必要があります。
それで。どうしてequals()を書き直した後、hashCode()を書き直すのでしょうか?
考えてみてください、バケット内で何かを見つけたい場合は、まずバケットを見つける必要があります。hashcode() を書き換えてもバケットが見つからない場合、equals() を書き換えるだけで何の意味があるでしょうか?