2

SOでは、ハッシュコードの実装とXOR演算子の使用に関する提案に関連するいくつかの回答を読みました。(例えば、Java hashCode() では XOR がよく使用されるのに、別のビット演算子はめったに使用されないのはなぜですか? )。

Eclipse を使用してfield、オブジェクトとtimestamplong であるハッシュコード関数を生成すると、出力は次のようになります。

public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result
        + field == null) ? 0 : field.hashCode());
  return result;
}

以下のように XOR 演算子を使用しない理由はありますか?

  result = prime * result + (int) (timestamp ^ (timestamp >>> 32));
4

1 に答える 1

3

Eclipse は安全な方法を取ります。素数、乗算、および加算を使用する計算方法は、単一の XOR よりも遅くなりますが、複数のフィールドがある状況では、全体的に優れたハッシュ コードが得られます。

String簡単な例を考えてみましょう。2 つのaとを持つクラスbです。使用できます

a.hashCode() ^ b.hashCode()

また

a.hashCode() * 31 + b.hashCode()

ここで、2 つのオブジェクトを考えます。

a = "ABC"; b = "XYZ"

a = "XYZ"; b = "ABC"

最初の方法は、XOR が対称であるため、同一のハッシュ コードを生成します。2 番目の方法では異なるハッシュ コードが生成されますが、これは良いことです。オブジェクトが等しくないからです。一般に、これらのオブジェクトのハッシュベースのコンテナーのパフォーマンスを向上させるために、等しくないオブジェクトにできるだけ頻繁に異なるハッシュ コードを持たせる必要があります。この31*a+b方法は、XOR よりもこの目標を達成します。

次のように、同じオブジェクトの一部を扱っている場合は注意してください。

timestamp ^ (timestamp >>> 32)

上記の議論ははるかに弱いです.2つのタイムスタンプに遭遇すると、それらの間の唯一の違いは、それらの上部と下部が交換されていることであり、交換aされたbフィールド値を持つ2つのオブジェクトよりも想像が困難です.

于 2013-04-18T10:45:19.747 に答える