2013-05-07 2 views
7

は、このクラスを検討メリット:パーフェクトハッシュ関数と

public final class MyDate { 
     private int year, month, day; 

     public MyDate(int year, int month, int day) { 
      this.year = year; 
      this.month = month; 
      this.day = day; 
     } 

     //Some stuff 

     @Override 
     public int hashCode() { 
      return ((year << 4) | month) << 5 | day; 
     } 
} 

メモリに我々が持っているので、これは完璧なハッシュ関数である:

enter image description here

をので、赤、5 bits店舗の日に( 1〜31)、黄色で4 bitsは月(1〜12)を格納し、その他は年(1〜16777215)を格納します。

完全なhashFunctionのメリットは何ですか? AFAIK、HashSetO(1)に追加/削除/含まれていることを保証できますが、他の利点がありますか?

私は多くのハッシュ関数が素数を使っているのを見ました。それを構築するには何が最良の方法ですか(私は完璧なハッシュ関数を作成するのはうれしいですか?


EDIT:素数について

は - >here

+0

あなたの完璧なハッシュ関数は、潜在的なハッシュ配列がすべての可能な値に適合するようにサイズ調整されている場合にのみ有益です(これはjdk HashSet/HashMapではほとんどありません)。 – jtahlborn

+0

私はそれを得ることができません:なぜ私は簡単に私は1つを必要とする新しいインスタンスを作成することができますハッシュセットに日付を入れて? – Andy

+0

@Andyこれはその例です – user2336315

答えて

8

完璧なハッシュ関数に答えあなたは何の衝突を持っていないだろうことを保証します。ただし、1つを使用できるようにするには、ハッシュする必要のあるキー値のセットを正確に把握しておく必要があります。

他のものは完全ではありませんが、(ハッシュ関数は衝突解決メカニズムと共に)そのような要件を持たず、とにかく計算が非常に速いので、しばしばより適切です。

1

Juampiによれば、それは高速です。 速いですか? おおよそO(1)。Redisは、ハッシュテーブルによるメモリ内の一定時間の検索の素晴らしい例です。

ハッシュの結果に正確に1つの要素のバケットがない場合は、equalsを使用して各項目を比較する必要があるので、O(1 + z)のルックアップが必要です。ここで、zはバケットサイズです。

はい、非常に遅いハッシュ関数は確かに素晴らしいアイデアではありません。