生成されたハッシュコードをキャッシュするため、不変オブジェクトを HashMap のキーとして持つ方が良いと読みました。
不変オブジェクトがデフォルトでハッシュコードをキャッシュするのはなぜですか? 不変オブジェクトをキーとして持つことの本当の利点はありますか?
それは実際には主な理由ではありません (不変オブジェクトはそのハッシュコードをキャッシュしない可能性があります)。
本当の (潜在的な) 問題は、キーがハッシュマップ内にある間にキーのハッシュコードが変更された場合、map.containsKey(modifiedKey)
キーがまだマップ内にあるにもかかわらず、への呼び出しが false を返す可能性があることです。
それにアクセスしてから反復する唯一の方法。
実際の結果は、マップの実装によって異なる場合があることに注意してください。
以下の不自然な例を参照してください。出力は次のとおりです。
偽
1
{1=abc}
つまり、マップはキーがもう存在しないと考えていますが、実際にはまだ存在しています。
public class Test2 {
public static void main(String[] args) {
Map<Mutable, String> map = new HashMap<> ();
Mutable m = new Mutable();
map.put(m, "abc");
m.i = 1;
System.out.println(map.containsKey(m));
System.out.println(map.size());
System.out.println(map);
}
public static class Mutable {
int i = 0;
@Override
public int hashCode() {
return i;
}
public String toString() {
return String.valueOf(i);
}
}
}
不変オブジェクトは変更されません。これは、HashMap
このキーでオブジェクトを検索するときに、ハッシュコードを再計算する必要がないことを意味します。一度計算すると、その値をキャッシュできます。
これはキャッシュとは何の関係もありませんhashCode()
(不変オブジェクトはその場で計算できます)。の結果の安定性に関係していhashCode()
ます。可変オブジェクトのhashCode()
場合、 は変化する可能性のある値に依存している可能性があります。これが発生すると、HashMap
.