Java Map::hashCode()冲突-为什么?

Java Map::hashCode()冲突-为什么?,java,map,hashcode,collision,Java,Map,Hashcode,Collision,下面的代码导致为两个映射生成相同的哈希代码,有什么想法吗 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("ca

下面的代码导致为两个映射生成相同的哈希代码,有什么想法吗


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

简单地更改密钥名称就足以使代码生成两个不同的哈希代码。

我怀疑这只是巧合。。。肯定会有冲突,在这种情况下,第一个值中的相关不同位看起来正在丢失,这是有效的

然而,这不应该有任何区别——任何使用哈希代码的东西都必须处理冲突

编辑:这只是计算散列的方式。此代码显示发生了什么:

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;
return (int)(value ^ (value >>> 32));
。。。和
Long.hashCode()
,如下所示:

return value ? 1231 : 1237;
return (int)(value ^ (value >>> 32));

考虑到他们碰巧在
Boolean.hashCode()
中选择的值,如果您的
long
值仅相距26(或26*2^32),那么您将遇到相同的问题。

我认为这只是巧合。从Javadoc for AbstractMap#hashCode()中:

映射的哈希代码定义为映射的entrySet()视图中每个条目的哈希代码之和

对于条目#hashCode():

返回此映射项的哈希代码值。映射条目e的哈希代码定义为:


因此,映射的哈希代码基于映射中包含的键和值。您只是遇到了一种奇怪的情况,两个映射具有相同的哈希代码,没有明显的原因。

冲突会发生。事实上,您可以重写hashCode(),使每个
HashMap
始终返回0,这是正确的(尽管它会使许多结构变慢)。

这不是巧合

字符串对象在两者中相同。相同的对象将给出相同的哈希代码