2012-04-03 3 views
2

なぜ容量は倍数または2でなければなりませんか? indexFor関数で "&"を使用する理由は? キーのハッシュコードを直接使用するのではなく、ハッシュ関数でハッシュを再計算するのはなぜですか?Java HashMapの実装について

この実装と「アルゴリズムの紹介」の説明との間には、いくつかの重要な違いがあると思います。

「>>>」とはどういう意味ですか?

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

誰でも教えていただけますか?私はいくつかのハッシュアルゴリズムを説明することができれば感謝します。 ありがとう!

+0

私は "&"を使用して知っている、キーは、制限されたスロットにマップすることができます。ハッシュマップの衝突に対する影響はどうですか? – lingguang1997

+0

'>>>'は符号なしの右シフトです。 Javaの通常の '>>'は符号ビットを保存して伝播し、負の数を負の値にします。シフトが発生すると、 '>>>'は符号ビットをゼロで埋めます。 –

答えて

5

これはパフォーマンスの最適化です。テーブルインデックスにハッシュコードをマッピングするための通常の方法は

table_index = hash_code % table_length; 

%オペレータが高価です。 table_lengthが2のべき乗である場合には、計算:

table_index = hash_code & (table_length - 1); 

は(かなり)より高価な剰余演算に相当します。

+0

これは、古いプロセッサ上のアセンブリでコーディングすることを学ぶことをお勧めします。 – biziclop

+0

危険ウィルロビンソン!ハッシュコードの50%は負の数なので、 'hash_code%table_length'は負の値になり、結果として' ArrayOutOfBoundsException'が発生します。使用可能な(すなわち安全な)インデックスを取得するには、 'Math.abs(hash_code%table_length) 'を使用する必要があります。 – Bohemian

+0

@Bohemian - はい、負の数は複雑になります。これは、負のハッシュコード値で正常に動作する2番目の方法のもう1つの利点です。 –

0

カーテンの後ろの男には注意を払わないでください。

実際のアルゴリズムは、開発者にとっての「気分が良い」、縮退したいくつかの奇妙なケースの修正、単純な伝統(ユーザーがしばしばあいまいな依存関係を生む)の組み合わせであることは間違いありません。

そして、この点に注意してください。

* Applies a supplemental hash function to a given hashCode, which 
* defends against poor quality hash functions. This is critical 
* because HashMap uses power-of-two length hash tables, that 
* otherwise encounter collisions for hashCodes that do not differ 
* in lower bits. Note: Null keys always map to hash 0, thus index 0. 

をネット:それが動作する限り、パフォーマンスが良いですが、あなたは気にしないでください。

+0

皆様のお返事ありがとうございます。彼らは私の質問に答えています。 – lingguang1997

関連する問題