【发布时间】:2012-02-22 15:44:05
【问题描述】:
我在 Windows XP 上的 Hotspot JDK 1.6 中运行以下代码, 我运行了两次,结果如下。
所以基本上看来object.hashcode() 也有冲突?
看起来它没有返回 VM 中的内存地址。
但是,JDK 中的注释说值应该是不同的,谁能解释一下?
在合理可行的情况下,hashCode 方法定义为 类 Object 确实为不同的返回不同的整数 对象。 (这通常是通过转换内部实现 对象的地址转换成整数,但是这个实现 技术是不需要的 JavaTM 编程语言。)
@return a hash code value for this object. @see java.lang.Object#equals(java.lang.Object) @see java.util.Hashtable
这是第一个结果:
i,hashcode(): 361,9578500
i,hashcode(): 1886,9578500
conflict:1886, 361
i,hashcode(): 1905,14850080
i,hashcode(): 2185,14850080
conflict:2185, 1905
9998
这是第二个结果:
i,hashcode(): 361,5462872
i,hashcode(): 1886,29705835
conflict:1887, 362
i,hashcode(): 1905,9949222
i,hashcode(): 2185,2081190
conflict:2186, 1906
9998
10000
我的代码:
@Test
public void testAddr()
{
Set<Integer> s = new TreeSet<Integer>();
Map<Integer, Integer> m = new TreeMap<Integer, Integer>();
Set<Object> os = new HashSet<Object>();
for(int i = 0; i < 10000; ++i)
{
Object o = new Object();
os.add(o);
Integer h = o.hashCode();
if((i == 361) || (i == 1886) || (i == 2185) || (i == 1905))
{
System.out.println("i,hashcode(): " + i + "," + h);
}
if(s.contains(h))
{
System.out.println("conflict:" + i + ", " + m.get(h));
}
else
{
s.add(h);
m.put(h, i);
}
}
System.out.println(s.size());
int c = 0;
for(Object o: os)
{
c++;
}
System.out.println(c);
}
【问题讨论】:
-
评论并没有说它将是不同的,而是他们会尝试使其与众不同但不提供任何保证
-
“在合理可行的范围内”,它会返回不同的代码。不保证。
-
尽可能实用是理解为什么会出现哈希码冲突的关键短语。这不是错误。
-
我的问题更多是:windows 的 Object.hashcode() 实现上的热点 jdk 是什么?它是返回对象的内存地址吗?如果是,那么这里应该是不同的,因为我在最后的代码下面,这意味着所有的对象还没有被 GC 收集;诠释 c = 0; for(对象 o: os) { c++; }