複合オブジェクトをハッシュする

EDIT: This question is not about bitwise operators and can't be answered with Why are XOR often used in java hashCode() but another bitwise operators are used rarely?

オブジェクトのハッシュ計算にはさまざまなアプローチがあります。

class A {
  public B b;
  public C c;

  @Override
  public boolean equals();
  @Override
  public int hashCode() {
   return c.hashCode() ^ b.hashCode(); //XOR
   return c.hashCode() + prime * b.hashCode();//SUM
   return Objects.hash(b,c);//LIB
  }
}

LIBメソッドはSUMを使用しているようですが、なぜXORより優れていますか?

この例はJavaで書かれていますが、この問題は数学と確率に関するものです。

11
追加された 著者 assylias,
追加された 著者 assylias,
Josh Blochは、 Effective Java で優れたハッシュコード実装について説明します。
追加された 著者 Edward Thomson,
Josh Blochは、 Effective Java で優れたハッシュコード実装について説明します。
追加された 著者 Edward Thomson,
通常、lib関数を使用するだけです。確率分布分析を実行して、データポイントがどのように分散されているかを判断する場合を除き、データセットとの衝突が多いのですか?
追加された 著者 CodeMonkeyForHire,
通常、lib関数を使用するだけです。確率分布分析を実行して、データポイントがどのように分散されているかを判断する場合を除き、データセットとの衝突が多いのですか?
追加された 著者 CodeMonkeyForHire,

12 答え

SUMはハッシュコードのすべてのビットを使用してハッシュを拡散することを保証します(これはintの32ビットです)。サブハッシュコード()の実装については想定しません。

XORはBとCのハッシュコードにそれがある場合にのみ同じプロパティを持ちます。そうでなければ、BとCハッシュコードの "有用な"ビットの数を最小限にし、より悪い分布を引き起こす可能性があります。 。 BとCが非常に小さい傾向にある整数なら、最初の数ビット(int.hashcode()は恒等関数)を使用するだけです。

5
追加された

SUMはハッシュコードのすべてのビットを使用してハッシュを拡散することを保証します(これはintの32ビットです)。サブハッシュコード()の実装については想定しません。

XORはBとCのハッシュコードにそれがある場合にのみ同じプロパティを持ちます。そうでなければ、BとCハッシュコードの "有用な"ビットの数を最小限にし、より悪い分布を引き起こす可能性があります。 。 BとCが非常に小さい傾向にある整数なら、最初の数ビット(int.hashcode()は恒等関数)を使用するだけです。

5
追加された

SUMはハッシュコードのすべてのビットを使用してハッシュを拡散することを保証します(これはintの32ビットです)。サブハッシュコード()の実装については想定しません。

XORはBとCのハッシュコードにそれがある場合にのみ同じプロパティを持ちます。そうでなければ、BとCハッシュコードの "有用な"ビットの数を最小限にし、より悪い分布を引き起こす可能性があります。 。 BとCが非常に小さい傾向にある整数なら、最初の数ビット(int.hashcode()は恒等関数)を使用するだけです。

5
追加された

SUMはハッシュコードのすべてのビットを使用してハッシュを拡散することを保証します(これはintの32ビットです)。サブハッシュコード()の実装については想定しません。

XORはBとCのハッシュコードにそれがある場合にのみ同じプロパティを持ちます。そうでなければ、BとCハッシュコードの "有用な"ビットの数を最小限にし、より悪い分布を引き起こす可能性があります。 。 BとCが非常に小さい傾向にある整数なら、最初の数ビット(int.hashcode()は恒等関数)を使用するだけです。

5
追加された

答えは(いつものように)です: "依存する"これはあなたのクラスによって異なります。

たとえば、

class X {
    T a, b;
    X(T _a, _b) { a = _a; b = _b }
}

+* 、または ^ のような対称演算子を使用しないでください( Tint X(1,2)X(2,1)をハッシュしています。 3つの "解"(xorまたはハッシュ値)が悪いです。

T が複合型の場合、参照のみが考慮されるため、3番目の解決策( Objects.hash())も悪い可能性がありますコード)。

1
追加された
より一般的には、デフォルトのhashCode実装を使用するオブジェクトだけがアイデンティティハッシングの対象です。そのようなオブジェクトはこの質問の対象外です。
追加された 著者 Basilevs,
1.用語「複合型」の誤用(CSに正式な定義がなく、例えば複素数を指す場合もあります)2.暗黙のhashCode()+ equals()契約の違反私の理解が不足している場所?
追加された 著者 Basilevs,
複合型とは何ですか?等しいオブジェクトが異なるハッシュコードを生成するのはなぜですか?
追加された 著者 Basilevs,
「複合型」はここでうまくいくのでしょうか?
追加された 著者 Basilevs,
3. Objects.hash()は、配列の参照をハッシュするだけです。例に配列がない場合、この引数は適用されません。
追加された 著者 Basilevs,
" T が複雑な型の場合は、参照のみが考慮されるため、3番目の解(Objects.hash())も悪い可能性があります。 Objects.hash(...)が参照する異なる参照を持つことができます。したがって、異なる参照で等しいオブジェクトを渡す場合、異なるハッシュコードが生じる可能性があります。それは私が書いたものであり、正しいと思います。
追加された 著者 U. Windl,
私は、特にJavaのような矛盾した言語について議論するとき、 Atomic かintrinsic_か primitive のいずれかで、/i>、複合はもう一方です。エッフェル塔には拡張タイプと参照タイプがあります。そして、Javaには存在しない平等性とハッシュコードに関する非常に明確な契約があります(そして、それがJavaで最も混乱する理由です)。
追加された 著者 U. Windl,
@Basilevs:複合型は明らかに非プリミティブ型です。つまり、真の参照型です。私はあなたが私が書いたことを理解していないときに、なぜこれをdownvoteするのか分かりません。
追加された 著者 U. Windl,

答えは(いつものように)です: "依存する"これはあなたのクラスによって異なります。

たとえば、

class X {
    T a, b;
    X(T _a, _b) { a = _a; b = _b }
}

+* 、または ^ のような対称演算子を使用しないでください( Tint X(1,2)X(2,1)をハッシュしています。 3つの "解"(xorまたはハッシュ値)が悪いです。

T が複合型の場合、参照のみが考慮されるため、3番目の解決策( Objects.hash())も悪い可能性がありますコード)。

1
追加された
複合型とは何ですか?等しいオブジェクトが異なるハッシュコードを生成するのはなぜですか?
追加された 著者 Basilevs,
3. Objects.hash()は、配列の参照をハッシュするだけです。例に配列がない場合、この引数は適用されません。
追加された 著者 Basilevs,
1.用語「複合型」の誤用(CSに正式な定義がなく、例えば複素数を指す場合もあります)2.暗黙のhashCode()+ equals()契約の違反私の理解が不足している場所?
追加された 著者 Basilevs,
「複合型」はここでうまくいくのでしょうか?
追加された 著者 Basilevs,
より一般的には、デフォルトのhashCode実装を使用するオブジェクトだけがアイデンティティハッシングの対象です。そのようなオブジェクトはこの質問の対象外です。
追加された 著者 Basilevs,
" T が複雑な型の場合は、参照のみが考慮されるため、3番目の解(Objects.hash())も悪い可能性があります。 Objects.hash(...)が参照する異なる参照を持つことができます。したがって、異なる参照で等しいオブジェクトを渡す場合、異なるハッシュコードが生じる可能性があります。それは私が書いたものであり、正しいと思います。
追加された 著者 U. Windl,
私は、特にJavaのような矛盾した言語について議論するとき、 Atomic かintrinsic_か primitive のいずれかで、/i>、複合はもう一方です。エッフェル塔には拡張タイプと参照タイプがあります。そして、Javaには存在しない平等性とハッシュコードに関する非常に明確な契約があります(そして、それがJavaで最も混乱する理由です)。
追加された 著者 U. Windl,
@Basilevs:複合型は明らかに非プリミティブ型です。つまり、真の参照型です。私はあなたが私が書いたことを理解していないときに、なぜこれをdownvoteするのか分かりません。
追加された 著者 U. Windl,

答えは(いつものように)です: "依存する"これはあなたのクラスによって異なります。

たとえば、

class X {
    T a, b;
    X(T _a, _b) { a = _a; b = _b }
}

+* 、または ^ のような対称演算子を使用しないでください( Tint X(1,2)X(2,1)をハッシュしています。 3つの "解"(xorまたはハッシュ値)が悪いです。

T が複合型の場合、参照のみが考慮されるため、3番目の解決策( Objects.hash())も悪い可能性がありますコード)。

1
追加された
複合型とは何ですか?等しいオブジェクトが異なるハッシュコードを生成するのはなぜですか?
追加された 著者 Basilevs,
より一般的には、デフォルトのhashCode実装を使用するオブジェクトだけがアイデンティティハッシングの対象です。そのようなオブジェクトはこの質問の対象外です。
追加された 著者 Basilevs,
1.用語「複合型」の誤用(CSに正式な定義がなく、例えば複素数を指す場合もあります)2.暗黙のhashCode()+ equals()契約の違反私の理解が不足している場所?
追加された 著者 Basilevs,
「複合型」はここでうまくいくのでしょうか?
追加された 著者 Basilevs,
3. Objects.hash()は、配列の参照をハッシュするだけです。例に配列がない場合、この引数は適用されません。
追加された 著者 Basilevs,
私は、特にJavaのような矛盾した言語について議論するとき、 Atomic かintrinsic_か primitive のいずれかで、/i>、複合はもう一方です。エッフェル塔には拡張タイプと参照タイプがあります。そして、Javaには存在しない平等性とハッシュコードに関する非常に明確な契約があります(そして、それがJavaで最も混乱する理由です)。
追加された 著者 U. Windl,
" T が複雑な型の場合は、参照のみが考慮されるため、3番目の解(Objects.hash())も悪い可能性があります。 Objects.hash(...)が参照する異なる参照を持つことができます。したがって、異なる参照で等しいオブジェクトを渡す場合、異なるハッシュコードが生じる可能性があります。それは私が書いたものであり、正しいと思います。
追加された 著者 U. Windl,
@Basilevs:複合型は明らかに非プリミティブ型です。つまり、真の参照型です。私はあなたが私が書いたことを理解していないときに、なぜこれをdownvoteするのか分かりません。
追加された 著者 U. Windl,

答えは(いつものように)です: "依存する"これはあなたのクラスによって異なります。

たとえば、

class X {
    T a, b;
    X(T _a, _b) { a = _a; b = _b }
}

+* 、または ^ のような対称演算子を使用しないでください( Tint X(1,2)X(2,1)をハッシュしています。 3つの "解"(xorまたはハッシュ値)が悪いです。

T が複合型の場合、参照のみが考慮されるため、3番目の解決策( Objects.hash())も悪い可能性がありますコード)。

1
追加された
1.用語「複合型」の誤用(CSに正式な定義がなく、例えば複素数を指す場合もあります)2.暗黙のhashCode()+ equals()契約の違反私の理解が不足している場所?
追加された 著者 Basilevs,
複合型とは何ですか?等しいオブジェクトが異なるハッシュコードを生成するのはなぜですか?
追加された 著者 Basilevs,
より一般的には、デフォルトのhashCode実装を使用するオブジェクトだけがアイデンティティハッシングの対象です。そのようなオブジェクトはこの質問の対象外です。
追加された 著者 Basilevs,
「複合型」はここでうまくいくのでしょうか?
追加された 著者 Basilevs,
3. Objects.hash()は、配列の参照をハッシュするだけです。例に配列がない場合、この引数は適用されません。
追加された 著者 Basilevs,
" T が複雑な型の場合は、参照のみが考慮されるため、3番目の解(Objects.hash())も悪い可能性があります。 Objects.hash(...)が参照する異なる参照を持つことができます。したがって、異なる参照で等しいオブジェクトを渡す場合、異なるハッシュコードが生じる可能性があります。それは私が書いたものであり、正しいと思います。
追加された 著者 U. Windl,
私は、特にJavaのような矛盾した言語について議論するとき、 Atomic かintrinsic_か primitive のいずれかで、/i>、複合はもう一方です。エッフェル塔には拡張タイプと参照タイプがあります。そして、Javaには存在しない平等性とハッシュコードに関する非常に明確な契約があります(そして、それがJavaで最も混乱する理由です)。
追加された 著者 U. Windl,
@Basilevs:複合型は明らかに非プリミティブ型です。つまり、真の参照型です。私はあなたが私が書いたことを理解していないときに、なぜこれをdownvoteするのか分かりません。
追加された 著者 U. Windl,

これは、 sum が提供する xor よりも優れた配布を提供するためです。

たとえば、 int ab の値が0〜7( 000 /code>バイナリの場合)、これら2つの引数の xor の結果は常に0〜7の間になります( xor は3ビットのみ変更)。乗算と sum を実行すると、値が0と7の範囲内にないため、より良い分布になります。

0
追加された
ところで、int hashCodeはその値ですか? HashMapや他のハッシュベースのアルゴリズムには悪い、ほとんどのユースケースの非一様分布の場合は非常に悪いでしょう。
追加された 著者 Basilevs,
実装に依存^^しかし、答えは、悲しいことに、しばしばはいです。
追加された 著者 C4stor,
@Basilevsはい、私はより広い、より良い、答え、感謝の固定を意味しました。
追加された 著者 Adam Siemion,

これは、 sum が提供する xor よりも優れた配布を提供するためです。

たとえば、 int ab の値が0〜7( 000 /code>バイナリの場合)、これら2つの引数の xor の結果は常に0〜7の間になります( xor は3ビットのみ変更)。乗算と sum を実行すると、値が0と7の範囲内にないため、より良い分布になります。

0
追加された
ところで、int hashCodeはその値ですか? HashMapや他のハッシュベースのアルゴリズムには悪い、ほとんどのユースケースの非一様分布の場合は非常に悪いでしょう。
追加された 著者 Basilevs,
実装に依存^^しかし、答えは、悲しいことに、しばしばはいです。
追加された 著者 C4stor,
@Basilevsはい、私はより広い、より良い、答え、感謝の固定を意味しました。
追加された 著者 Adam Siemion,

これは、 sum が提供する xor よりも優れた配布を提供するためです。

たとえば、 int ab の値が0〜7( 000 /code>バイナリの場合)、これら2つの引数の xor の結果は常に0〜7の間になります( xor は3ビットのみ変更)。乗算と sum を実行すると、値が0と7の範囲内にないため、より良い分布になります。

0
追加された
ところで、int hashCodeはその値ですか? HashMapや他のハッシュベースのアルゴリズムには悪い、ほとんどのユースケースの非一様分布の場合は非常に悪いでしょう。
追加された 著者 Basilevs,
実装に依存^^しかし、答えは、悲しいことに、しばしばはいです。
追加された 著者 C4stor,
@Basilevsはい、私はより広い、より良い、答え、感謝の固定を意味しました。
追加された 著者 Adam Siemion,

これは、 sum が提供する xor よりも優れた配布を提供するためです。

たとえば、 int ab の値が0〜7( 000 /code>バイナリの場合)、これら2つの引数の xor の結果は常に0〜7の間になります( xor は3ビットのみ変更)。乗算と sum を実行すると、値が0と7の範囲内にないため、より良い分布になります。

0
追加された
ところで、int hashCodeはその値ですか? HashMapや他のハッシュベースのアルゴリズムには悪い、ほとんどのユースケースの非一様分布の場合は非常に悪いでしょう。
追加された 著者 Basilevs,
実装に依存^^しかし、答えは、悲しいことに、しばしばはいです。
追加された 著者 C4stor,
@Basilevsはい、私はより広い、より良い、答え、感謝の固定を意味しました。
追加された 著者 Adam Siemion,