Tom*_*ine 12
给定合理的对象集合,很可能有两个具有相同哈希码的对象.在最好的情况下,它成为生日问题,与数以万计的对象发生冲突.在实践中,使用相对较小的可能哈希码池创建对象,并且仅使用数千个对象就可以容易地发生冲突.
使用内存地址只是获取稍微随机数的一种方法.Sun JDK源具有一个开关,可以使用安全随机数生成器或常量.我相信IBM(曾经?)使用快速随机数生成器,但它根本不安全.记忆地址文档中的提及似乎具有历史性(大约十年前,具有固定位置的对象句柄并不罕见).
这是几年前我写的一些代码,用于演示冲突:
class HashClash {
public static void main(String[] args) {
final Object obj = new Object();
final int target = obj.hashCode();
Object clash;
long ct = 0;
do {
clash = new Object();
++ct;
} while (clash.hashCode() != target && ct<10L*1000*1000*1000L);
if (clash.hashCode() == target) {
System.out.println(ct+": "+obj+" - "+clash);
} else {
System.out.println("No clashes found");
}
}
}
Run Code Online (Sandbox Code Playgroud)
RFE澄清文档,因为这种方式过于频繁:CR 6321873
Ric*_*dOD 11
我认为对象的hashCode方法的文档说明了答案.
"尽管相当实用,但是由Object类定义的hashCode方法确实为不同的对象返回不同的整数.(这通常通过将对象的内部地址转换为整数来实现,但JavaTM不需要此实现技术编程语言.)"
想一想.有无数个潜在对象,只有40亿个哈希码.显然,无限的潜在对象共享每个哈希码.
Sun JVM要么将Object哈希代码基于对象的稳定句柄,要么缓存初始哈希代码.GC期间的压缩不会改变hashCode().如果确实如此,一切都会破裂.
| 归档时间: |
|
| 查看次数: |
10018 次 |
| 最近记录: |