2016-04-15 104 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()); 
    }