7

座標をキーとして持つ HashMap があります。

座標には、x、y、z 座標を保持する 3 つの long があります。(座標はカスタム クラスである必要があり、座標は long である必要があります)。

ここで、次のようにして、たとえばフィールド [5, 10, 4] にアクセスできるようにしたいと考えていますhashMap.get(new Coordinate(5, 10, 4))

equals メソッドを実装しましたが、hashCode の実装も提供する必要があるようです。私の質問は、3 つの long から一意の hashCode を生成するにはどうすればよいですか? .

追加: 外部ライブラリからのハッシュ ジェネレーターの使用はオプションではありません。

4

5 に答える 5

17

Joshua Blochは、彼の「Effective Java」の第3章で、CoordinateクラスのequalsとhashCodeを作成する方法を説明しています。

このような:

public class Coordinate
{
    private long x;
    private long y;
    private long z;

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Coordinate that = (Coordinate) o;

        if (x != that.x) return false;
        if (y != that.y) return false;
        if (z != that.z) return false;

        return true;
    }

    @Override
    public int hashCode()
    {
        int result = (int) (x ^ (x >>> 32));
        result = 31 * result + (int) (y ^ (y >>> 32));
        result = 31 * result + (int) (z ^ (z >>> 32));
        return result;
    }
}
于 2011-04-20T12:25:36.260 に答える
4

Javaでは、標準hashCode()メソッドintは32ビットであるを返します。

データ型はlong64ビットです。したがって、3 sは192ビットの情報を意味します。もちろんlongハッシュ関数によって32ビットのハッシュ値に一意にマッピングすることはできません。

ただし、HashMapは一意のハッシュを必要とせず、衝突が発生したときにそれを処理するだけです。

単純な方法は、文字列、つまり「x、y、z」を作成してから、文字列をハッシュすることです。

値を一緒にXOR:ingすることもできます。

int hashCode()
{
  return (int) (x ^ y ^ z);
}
于 2011-04-20T12:25:40.010 に答える
2

3 つの long から一意の hashCode を生成するにはどうすればよいですか?

その必要はありません。ハッシュ コードは一意である必要はありません。

于 2011-04-20T12:26:56.907 に答える
1

ハッシュコードと HashMap で使用される一意のキーには違いがあることに注意してください。

Coordinate クラスのハッシュコードは、一意である必要はまったくありません...

ハッシュコードの適切な解決策は次のとおりです。

(int)(x ^ (x >> 32) ^ y ^ (y >> 32) ^ z ^ (z >> 32));

これは、XOR 演算された各 long の 2 つの半分の XOR です。

于 2011-04-20T12:32:42.317 に答える