2016-04-15 79 views
4

我定义我类如:哈希码的均匀分布()

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 

的问题是,散列码()可以返回一个负值所以

arr[h+i % h] = k; 

可以返回错误出数组索引的。这就是为什么,因为我改变了我的代码(根据我的搜索,以避免hashCode()方法返回负值):

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

所以,如果我做这样,做的哈希码的均匀分布()来改变或不?我的意思是从两个不同的对象获得相同的价值的可能性会增加或不增加?

+0

,你怎么样能够创建对象作为键的键。它应该给编译器错误,因为键入的参数数量不正确 Roshan

+0

是的,我的错误。我也编辑过它。谢谢 – nd07

+0

你可以看看有很好分布的杂音哈希。并且不能具有价值 –

回答

2

Object.hash()有一个非常简单的hashCode,它对简单的例子来说并不是特别统一。例如Objects.hash(“B”,“B”)和Objects.hash(“A”,“a”)具有相同的hashCode。 (和BTW很简单,我可以工作了这一点在我的头上)

而且每Objects.hashCode("a", "a")Objects.hashCode("z", "z")之间,4065和4865这看起来并不特别均匀,尤其高位比特之间。

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

+0

如果是这样。哪个方法更好地避免散列码的负值() 1.如上 2.避免在这一步的负值:arr [h + i%h] = k。我的意思是我使用Math.abs(h + i%h)转换为正值。 – nd07

+0

@ nd07你想在这里避免'Math.abs',因为这可以返回一个负数o_O'(hash&0x7FFF_FFFF)%buckets'比较好。注意:'Math.abs(Integer.MIN_VALUE)== Integer.MIN_VALUE',你很难找出很长一段时间。 –

+1

是的,感谢您的支持 – nd07

2

请看看MurmurhashMurmurHash - what is it? 幸运的是,Google guava已经为此做好了准备。

番石榴方式就像例如 下面我们就用上面的类以下类

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

我有我的方法来生成散列码像下面

/** 
    * getMurmur128Hash. 
    * 
    * @param content 
    * @return HashCode 
    */ 
    public static HashCode getMurmur128Hash(String content) { 
     final HashFunction hf = Hashing.murmur3_128(); 
     final HashCode hc = hf.newHasher().putString(content, Charsets.UTF_8).hash(); 
     return hc; 
    } 
    /** 
    * getAbsMurmur128HashAsLongVal. 
    * 
    * @param content 
    * @return Long Absolute value of Long for the HashCode. 
    */ 
    public static Long getAbsMurmur128HashAsLongVal(String content) { 
     return Math.abs(getMurmur128Hash(content).asLong()); 
    }