以下代码导致为两个地图生成相同的哈希码,任何想法?
import java.util.HashMap;
import java.util.Map;
public class Foo
{
@SuppressWarnings("unchecked")
public static void main (String[] args)
{
Map map;
map = new HashMap();
map.put("campaignId", 4770L);
map.put("location", "MINI_PROFILE");
map.put("active", "true");
map.put("lazy", true);
System.out.println(map.hashCode());
map = new HashMap();
map.put("campaignId", 4936L);
map.put("location", "MINI_PROFILE");
map.put("active", "true");
map.put("lazy", false);
System.out.println(map.hashCode());
}
}
结果是:
-1376467648
-1376467648
只需更改密钥名称就足以使代码生成两个不同的哈希码。
答案 0 :(得分:9)
简直巧合,我怀疑...... 绑定是冲突,在这种情况下,它看起来像第一个值中的相关不同位有效丢失。
然而,它应该没有任何区别 - 使用哈希码的任何东西都必须来应对冲突。
编辑:这就是哈希计算的方式。此代码显示了正在发生的事情:
import java.util.*;
public class Test
{
@SuppressWarnings("unchecked")
public static void main (String[] args)
{
AbstractMap.SimpleEntry[] entries = {
new AbstractMap.SimpleEntry("campaignId", 4770L),
new AbstractMap.SimpleEntry("campaignId", 4936L),
new AbstractMap.SimpleEntry("lazy", true),
new AbstractMap.SimpleEntry("lazy", false)
};
for (AbstractMap.SimpleEntry entry : entries) {
System.out.println(entry + ": " + entry.hashCode());
}
}
}
结果:
campaignId=4770: -1318251287
campaignId=4936: -1318251261
lazy=true: 3315643
lazy=false: 3315617
因此,在一对中,第一张地图的散列值比第二张地图少26 ,而在另一对地图中,第一张地图的散列值比第二张地图少26 更多
AbstractMap
只是对哈希值求和(确保排序无关紧要的一种方法),所以两者最终会得到相同的哈希码。
这真的是Boolean.hashCode()
,看起来像这样:
return value ? 1231 : 1237;
...和Long.hashCode()
看起来像这样:
return (int)(value ^ (value >>> 32));
考虑到它们恰好在Boolean.hashCode()
中选择的值,如果您的long
值仅相差26(或相隔26 * 2 ^ 32),那么您将遇到同样的事情。
答案 1 :(得分:6)
我认为这只是一个巧合。从用于AbstractMap的Javadoc #hashCode():
映射的哈希码被定义为映射的entrySet()视图中每个条目的哈希码的总和。
对于Entry#hashCode():
返回此映射条目的哈希码值。映射条目e的哈希码被定义为:
(e.getKey()==null ? 0 : e.getKey().hashCode()) ^
(e.getValue()==null ? 0 : e.getValue().hashCode())
因此,地图的哈希码基于键和地图中包含的值。您只是遇到一种奇怪的情况,即两张地图具有相同的哈希码,没有明显的原因。
答案 2 :(得分:3)
发生碰撞。实际上,您可以覆盖hashCode()以始终为每个HashMap
返回0并且它是正确的(尽管它会使很多结构慢)。
答案 3 :(得分:0)
这不是巧合。
两者中的String对象相同。相同的对象将提供相同的哈希码。