哈希码的均匀分布()

时间:2016-04-15 08:54:41

标签: java hashcode hash-collision

我将我的课程定义为:

final class Key<T extends Comparable<T>> {
    private final T q;
    private final T o;
    public Key(T q1, T o1) {
        q = q1;
        o = o1;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj != null && obj instanceof Key) {
            Key<T> s = (Key<T>)obj;
            return q.equals(s.q) && o.equals(s.o);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(q,o);
    }
}

我还定义了一个包含对象键的数组。例如:

Object arr[] = new Object[100];
Key<String> k = new Key<>("a","b");
int h = k.hashcode();
...
arr[h+i % h] = k; //i from 1 to 10 for example

问题是hashcode()可以返回负值,所以

arr[h+i % h] = k;

可以从数组索引中返回错误。这就是为什么我改变我的代码(基于我的搜索避免hashcode()返回负值):

@Override
        public int hashCode() {
            return (Objects.hash(q,o)&0x7FFFFFFF);
        }

因此,如果我这样做,是否会改变hashcode()的均匀分布?我的意思是从两个不同的对象获得相同值的概率会增加与否?

2 个答案:

答案 0 :(得分:2)

Object.hash()有一个非常简单的hashCode,对于简单的例子来说并不是特别统一。例如Objects.hash(“B”,“B”)和Objects.hash(“A”,“a”)具有相同的hashCode。 (顺便说一下,我可以在脑海中解决这个问题)

Objects.hashCode("a", "a")Objects.hashCode("z", "z")之间的每一个都介于4065和4865之间,看起来并不是特别均匀,尤其是高位。

在这种情况下,我认为你可以说你没有让事情变得更糟。

答案 1 :(得分:2)

请查看MurmurhashMurmurHash - what is it? 幸运的是,谷歌番石榴已经为此做好了实施。

番石榴方式就像下面的例子 我们有以下课程

SELECT ReadOutID, Identifier, ECU, FileTime, FileName, Name, [Value] FROM ( SELECT dr.ReadOutID, dv.Identifier, dv.ECU, dr.FileTime, dr.FileName, dve.Name, dv.[Value], DENSE_RANK() OVER (PARTITION BY dve.Name ORDER BY dr.FileTime DESC) as drnk FROM db_ddladmin.Data_Readouts dr INNER JOIN db_ddladmin.Data_Values dv ON dr.ReadOutID = dv.ReadOutID INNER JOIN db_ddladmin.Data_Vehicles dve ON dr.VehicleID = dve.ID ) as rv WHERE drnk = 1;

使用上面的类我有我的方法来生成如下所示的哈希码

import com.google.common.hash.HashCode;
 import com.google.common.hash.HashFunction;
 import com.google.common.hash.Hashing;