OpenJDKの再ハッシングメカニズム

http://www.docjar.com/htmlでこのコードを見つけました/api/java/util/HashMap.java.html を参照してください。

  264       static int hash(int h) {
  265          //This function ensures that hashCodes that differ only by
  266          //constant multiples at each bit position have a bounded
  267          //number of collisions (approximately 8 at default load factor).
  268           h ^= (h >>> 20) ^ (h >>> 12);
  269           return h ^ (h >>> 7) ^ (h >>> 4);
  270       }

誰かがこれにいくつかの光を当てることができますか?このコードはなぜこのコードがあるのか​​を示していますが、悪いハッシュ値をどのように改善するかポジションが衝突]をクリックします。これらのマジックナンバーはどういう意味ですか?

18

1 答え

それが意味をなさせるために、HashMapがバケットに物を割り当てる方法の理解と組み合わせなければなりません。これはバケットインデックスを選択する簡単な関数です:

static int indexFor(int h, int length) {
    return h & (length-1);
}

つまり、デフォルトのテーブルサイズが16の場合、ハッシュの4つの最下位ビットだけが実際にバケットを割り当てるのに重要であることがわかります! (16-1 = 15、ハッシュを1111bでマスクする)

あなたのhashCode関数が返された場合、これは明らかに悪いニュースです:

10101100110101010101111010111111

01111100010111011001111010111111

11000000010100000001111010111111
//etc etc etc

そのようなハッシュ関数は、その作者が見ることのできる方法では「悪い」ものではないようです。しかし、地図をバケット、ブーム、MapFail(tm)を割り当てる方法と組み合わせると、

hが32ビットの数値であることを覚えておけば、それらは魔法の数字ではありません。これは、数値の最上位ビットを最下位ビットに体系的にコーディングしています。この目的は、バイナリで表示されたときに「どこでも」発生する数字の「相違」が最下位ビットで見えるようにすることです。

バイナリ表現の任意の場所で発生する相違点は、バケット処理の対象となるビットに圧縮されるため、関連するLSBが同じである異なる数値の数が大幅に制限されるため、衝突は制限されます。

22
追加された
詳しい説明をありがとう!
追加された 著者 c_maker,