Javadoc にもかかわらず、アルゴはアドレスを入力としてしか使用できません。これは、新しいオブジェクトが eden 空間で同じアドレスを使用しても、同じ hashCode を持たないことを意味します。
使用している可能性のあるアルゴリズムは多数ありますが、すべてがアドレスを使用しているわけではありません。
注: hashCode() は 31 ビットです。
ところで、ホットスポットで設定できますUnsafe.putInt(object, 1, value)
。
Set<Integer> ints = new LinkedHashSet<>();
int negative = 0, nonneg = 0;
for (int i = 0; i < 100; i++) {
System.gc();
for (int j = 0; j < 100; j++) {
int h = new Object().hashCode();
ints.add(h);
if (h < 0) negative++;
else nonneg++;
}
}
System.out.println("unique: " + ints.size() + " negative: " + negative + " non-neg: " + nonneg);
版画
unique: 10000 negative: 0 non-neg: 10000
安全でない使用
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
Object o = new Object();
System.out.println("From header " + Integer.toHexString(unsafe.getInt(o, 1L)));
// sets the hashCode lazily
System.out.println("o.hashCode() " + Integer.toHexString(o.hashCode()));
// it's here now.
System.out.println("after hashCode() From header " + Integer.toHexString(unsafe.getInt(o, 1L)));
unsafe.putInt(o, 1L, 0x12345678);
System.out.println("after change o.hashCode() " + Integer.toHexString(o.hashCode()));
版画
From header 0
o.hashCode() 2260e277
after hashCode() From header 2260e277
after change o.hashCode() 12345678