0

これが何度も聞かれていることは知っていますが、私の質問に対する正確な答えが見つかりません。

有効な Java の第 3 章には、equals メソッドと共にハッシュコードをオーバーライドする必要がある理由を示して説明するシナリオがあります。大部分は理解できますが、理解できない部分があります。

equals メソッドをオーバーライドする特定のクラスがありますが、hashCode メソッドはオーバーライドしません。オブジェクトはキーとしてマップに配置されます

Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
m.put(new PhoneNumber(707, 867, 5309), "Jenny");

get別の等しいオブジェクト ( )を使用すると、単純に等しいオブジェクトに対して等しい値を返すようにハッシュコードがオーバーライドされないため、null が返されることを理解してm.get(new PhoneNumber(707, 867, 5309))います (異なるハッシュコードのために別のバケットでオブジェクトを検索するため)。

しかし、私の理解によると、その状況では、2 つのオブジェクトのハッシュコードが常に異なるものを返すという保証はありません。たまたま同じハッシュコードを返したらどうなるでしょうか?

この部分で説明されていると思います

2 つのインスタンスがたまたま同じバケットにハッシュされたとしても、get メソッドはほぼ確実に null を返します。HashMap には、各エントリに関連付けられたハッシュ コードをキャッシュする最適化があり、ハッシュ コードが一致しない場合はオブジェクトの等価性をわざわざチェックしないためです。一致しません。

私はただキャッシュのことを理解していません。誰かがこれを詳しく説明できますか?

また、私はすでに宿題をしており、関連する質問を見つけました

各エントリに関連付けられたハッシュ コードをその get メソッドにキャッシュする HashMap 最適化の影響

しかし、私は受け入れられた回答に満足していません。また、回答者はコメントで次のように述べています

ハッシュ コードは任意の int にすることができるため、各ハッシュ コードは独自のバケットを持つことはできません。その結果、異なるハッシュ コードを持つ一部のオブジェクトが同じバケットに配置されます。

私は完全に同意しません。私の理解では、異なるハッシュコードが同じバケットに入ることはありません。

4

2 に答える 2

0

これが「2 つのインスタンスがたまたま同じバケットにハッシュされたとしても」と言われても、それらが同じハッシュコードを持っているという意味ではありません。異なるハッシュコードでも同じバケットにマッピングできます [ハッシュについて読む]。

そのため、キーが同じバケットにハッシュされたとしても、(キャッシュの最適化により) 関連する要素に対して .equals が呼び出されない場合があります (ハッシュコードが一致しないため)。したがって、関連する要素が同じバケットに存在する場合でも、.equals を介して比較されることはなく、「見つからない」可能性があります。

于 2013-04-19T03:46:40.627 に答える