繁体   English   中英

仅包含整数的对象的哈希码

[英]Hashcode for objects with only integers

您如何以通用(和高性能)的方式实现哈希码,同时最小化具有 2 个或更多整数的对象的冲突?

更新:正如许多人所说,你不能完全消除碰撞(老实说没有考虑过)。 所以我的问题应该是如何以适当的方式最大限度地减少碰撞,并进行编辑以反映这一点。

使用 NetBeans 的自动生成失败; 例如:

public class HashCodeTest {
    @Test
    public void testHashCode() {
        int loopCount = 0;
        HashSet<Integer> hashSet = new HashSet<Integer>();
        for (int outer = 0; outer < 18; outer++) {
            for (int inner = 0; inner < 2; inner++) {
                loopCount++;
                hashSet.add(new SimpleClass(inner, outer).hashCode());
            }
        }
        org.junit.Assert.assertEquals(loopCount, hashSet.size());
    }

    private class SimpleClass {
        int int1;
        int int2;

        public SimpleClass(int int1, int int2) {
            this.int1 = int1;
            this.int2 = int2;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 17 * hash + this.int1;
            hash = 17 * hash + this.int2;
            return hash;
        }
    }
}

对于具有 2 个或更多整数的对象,您能否以一种通用(和高性能)的方式实现没有冲突的哈希码?

当散列到 32 位(一个整数)由超过 32 位(如 2 个或更多整数)组成的东西时,从技术上讲不可能零冲突。

这是 eclipse 自动生成的:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + getOuterType().hashCode();
    result = prime * result + int1;
    result = prime * result + int2;
    return result;
}

使用此代码,您的测试用例通过了...

PS:不要忘记实施equals()

没有办法完全消除 hash 次碰撞。 您的方法基本上是减少冲突的首选方法。

创建零冲突的 hash 方法是不可能的。 hash 方法的想法是获取大量对象并将其映射到较小的整数集。 您能做的最好的事情就是尽量减少您在对象子集中发生的碰撞次数。

正如其他人所说,尽量减少碰撞比消除碰撞更重要——尤其是因为你没有说你的目标是多少桶。 与 2 个桶中的 5 个项目相比,与 1000 个桶中的 5 个项目零碰撞要容易得多,即使有很多桶。 1000 个桶和 1001 个桶的碰撞看起来可能非常不同。

另一件需要注意的事情是,您提供的 hash 很有可能甚至不是 HashMap 最终使用的那个。 例如,如果您查看OpenJDK HashMap 代码,您会发现您的密钥的哈希代码是通过一个私有的hash方法(该链接中的第 264 行)重新哈希处理的。 因此,如果您正在努力创建一个精心构建的自定义 hash function 以减少碰撞(而不是简单的自动生成的碰撞),请确保您也了解谁将使用它,以及如何使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM