0

私は今、Apache commons langのHashCodeBuilderのような組み込みユーティリティを利用できることを知っていますが、自分でそれを実装する方法を理解しようとしていて、http://en.wikipedia.org/wiki/Java_hashCodeでEmployeeクラスのhascode関数の例に出くわしました()

Googleのどこでも、ゼロ以外の値に奇数の素数を掛けてからインスタンス変数と合計するなど、同じ種類の手法が提案されています(インスタンス変数に対して実行します)。

質問:-

1) 一意であるため、employeeId を hascode として返すことができないのはなぜですか。シンプルで、hascode の目的を果たします。ユニークでない場合は、おそらくそのようなテクニックが必要です。そうですか?

2)従業員IDが一意ではない場合でも、奇数の素数を掛けることが提案されているのはなぜですか? なぜいまいましい整数を取ることが良いと見なされないのですか?

アップデート:-

ピーター私はあなたがそれが印刷されたと述べた例を実行しました

[0, 32, 64, 96, 128, 160, 192, 224, 288, 256, 352, 320, 384]

[0, 32, 64, 96, 128, 160, 192, 224, 288, 256, 352, 320, 384]

私はあなたがあなたの答えで述べたように概念を理解することを期待していたように、今のところその出力を想定しています

[373, 343, 305, 275, 239, 205, 171, 137, 102, 68, 34, 0]

[0, 34, 68, 102, 137, 171, 205, 239, 275, 305, 343, 373]

コメントで示唆したように、この例では、一意のハッシュコードでも同じバケットになる可能性があることを示しました。この例は、この動作をどのように示しましたか? integers の場合は 373 で、integers2 の場合は 0 が同じバケットになるということですか?

この例で素数はどの程度役に立ち、34 は役に立たなかったのでしょうか?

4

1 に答える 1

2

なぜ、employeeId を hascode として返すことができないのですか。シンプルで、hascode の目的を果たします。ユニークでない場合は、おそらくそのようなテクニックが必要です。そうですか?

その独自性は重要ではありません。素数を乗算することは、複数のフィールドを 1 つの hashCode にマージする良い方法ですが、1 つしかないように聞こえるため、大きな違いはありません。

従業員IDが一意ではない場合でも、奇数の素数を掛けることが提案されているのはなぜですか? なぜいまいましい整数を取ることが良いと見なされないのですか?

偶数を掛けると、hashCode の最下位ビットは何になりますか? それはどのくらいランダム/有用ですか?


注: Integer のすべての hashCode() は一意ですが、整数値の適切な組み合わせを取得し、それらが HashMap の容量に縮小されると、実際には同じバケットにマップされます。この例では、すべてのエントリが同じバケットにマッピングされているため、エントリは追加されたときと逆の順序で表示されます。

HashSet<Integer> integers = new HashSet<>();
for (int i = 0; i <= 400; i++)
    if ((hash(i) & 0x1f) == 0)
        integers.add(i);
HashSet<Integer> integers2 = new HashSet<>();
for (int i = 400; i >= 0; i--)
    if ((hash(i) & 0x1f) == 0)
        integers2.add(i);
System.out.println(integers);
System.out.println(integers2);


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);
}

版画

[373, 343, 305, 275, 239, 205, 171, 137, 102, 68, 34, 0]
[0, 34, 68, 102, 137, 171, 205, 239, 275, 305, 343, 373]
于 2013-10-06T13:44:31.793 に答える