6

私が正しく覚えていれば、Object() 型のオブジェクトの Java でのデフォルトの hashCode() 実装は、オブジェクトのメモリ アドレスを返すことです。独自のクラスを作成するとき、hashCode() をオーバーライドして、それらを HashMap() などのハッシュ関連のコレクションに挿入したときに適切に機能するようにしたいということを読みました。しかし、メモリアドレスが悪いのはなぜですか?

確かに、最終的にメモリが不足し、衝突が発生しますが、これが問題であると思われる唯一のケースは、大量のデータを処理していてメモリがほとんどない場合であり、パフォーマンスに影響を与え始めます。 Java のハッシュ関連のコレクションは、連鎖によって衝突を解決します (バケットは、同じハッシュコード/インデックスに解決された値のリストにリンクします)。

4

4 に答える 4

30

すべてのオブジェクトが一意である場合、デフォルトの実装は正常に機能します。しかし、 equals() をオーバーライドすると、異なるアドレスを持つオブジェクトが互いに同等である可能性があることを暗に示しています。その場合、hashCode() もオーバーライドする必要があります。

String クラスを考えてみましょう。

String s1 = new String("foo");
String s2 = new String("foo");

これら 2 つの文字列は等しいため、ハッシュ コードも等しい必要があります。しかし、それらは異なるアドレスを持つ別個のオブジェクトです。

s1 == s2         // false, different addresses
s1.equals(s2)    // true, same contents

アドレスをハッシュ コードとして使用するとエラーになります。したがって、String は hashCode() をオーバーライドして、等しい文字列が等しいハッシュ コードを持つようにします。これは、次の hashCode() の規約を満たすのに役立ちます。

a.equals(b)が真の場合、a.hashCode() == b.hashCode().

結論: equals() をオーバーライドする場合は、hashCode() もオーバーライドします。

于 2013-04-12T18:08:40.457 に答える
1

オブジェクトをハッシュマップに配置するときに使用される正確なキー オブジェクトは、後でプログラムでマップにアクセスするために使用できない場合があります。したがって、 equals メソッドをオーバーライドすることになります。equals メソッドをオーバーライドすると、それらのハッシュコードも等しいことを確認します。そうしないと、ハッシュマップからオブジェクトを取得できません。

于 2014-04-01T13:58:55.510 に答える
0

メソッドを使用しない間は、equalsを定義しなくてもかまいませんhashCodeが、その後、 の契約はhashCodeオブジェクトに対して同じ結果を与えることになり、それは等しくなります。あなたはそれが確実ではないので、自分で書き直す必要があります

ハッシュコード

于 2013-04-12T18:07:59.830 に答える
0

どの hashCode() 実装をデータ構造で使用するかを決定することは、ハッシュマップ API の暗黙的な部分です。

特定の API に、厳密には処理されない情報を提供すると、制御が手から離れてしまいます。

デフォルトの hashCode() 実装を使用すると、管理したいキーがメモリ アドレスに結合されますが、これはあなたによって処理されず、制御することはできません。

ある日、一貫性とパフォーマンスの向上のためにオブジェクトをメモリ内で移動する、特定のメモリ オプティマイザを使用したいとします。キーの元のハッシュされたアドレスを保持しているため、データ構造を使用できなくなります。

より実用的な観点では、

プログラム全体でデータ構造から値を取得するには、以前に (別のデータ構造を使用して) 挿入したすべてのキーへの参照を保持する必要があります。オブジェクトの状態が「似ている」キーを使用することはできません。

Person steve1 = new Person("Steve","21","engineer");
Person steve2 = new Person("Steve","21","engineer");

map.put(steve1,"great worker");

map.get(steve2); 
// returns null because "steve2" is not considered a key like "steve1"

map.get(steve1); 
// returns "great worker"
于 2016-02-26T09:07:19.880 に答える