2017-03-09 4 views
1

私はこのコードを見てきました。私はこのような方法でイコールを実装したことはありません。私に打撃を与えるのは、それが本当に「きちんとしている」ということでした。これは合法ですか?

しかし、私が疑わしい前にこのアプローチを見たことがないという事実。 Java equalsとhashCodeの契約によれば、次の実装は合法ですか?

+0

これは、同じインスタンスかどうか、またはインスタンスであるかどうか(同じ場合にnullでない場合)をチェックし、ハッシュを比較します。これは悪い考えではないようですが、私は何かが恋しくなるかもしれません – AxelH

+0

また、 'getClass()'ではなく 'instanceof'を本当に使いたいことを確かめてください - http://stackoverflow.com/q/596462/2513200で引数を選んでくださいまたは他のもの。 'instanceof'を使うとき、対称性を間違って壊すのは非常に簡単です。 – Hulk

答えて

1

すでに他の回答に記載されている理由はおそらく悪い考えです。 「法的」な側面については

Contract of Object.equals状態

ザ・メソッドがnull以外のオブジェクト参照上の同値関係を実装等しい:

  • それは再帰:null以外のために参照値x、x.equals(x)はtrueを返す必要があります。
  • 対称です。null以外の参照値xとyについて、y.equals(x)がtrueを返す場合に限り、x.equals(y)はtrueを返す必要があります。
  • 推移的である:x.equals(y)がtrueを返し、y.equals(z)がtrueを返した場合、x.equals(z)はtrueを返す。
  • null以外の参照値xおよびyに対して、x.equals(y)の複数の呼び出しは、オブジェクトの等価比較で使用される情報が変更されていない限り、一貫してtrueを返し、常にfalseを返します。
  • null以外の参照値xの場合、x.equals(null)はfalseを返す必要があります。ステップバイ

ステップ:

  • 再帰:はい、原因this == o
  • 対称に:原因instanceofの使用に、私たちがすることで、すべてのスーパークラスとサブクラス調べる必要があります
  • 推移:対称性要件によります。そうでない場合はあります。
  • 整合性:あり
  • x.equals(null)はfalseを返す必要があります: - Any reason to prefer getClass() over instanceof when generating .equals()?への回答を参照してくださいはい、原因instanceof

にそうビューの純粋に法的な観点から、それはあなたの継承階層accross他の実装は、対称性と推移性に違反するかどうかによって異なります。

しかし、それ以外に、hashCodeが同等でないインスタンスに対して異なる値を生成する必要がないということを考えると、通常、等価を定義するのは良い方法ではありません。


例:二つのフィールドxy

class Point { 
    final int x; 
    final int y 

    public Point(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 
} 

不変点クラス - >2^32 * 2^32 = 2^64異なる状態が、唯一2^32可能なハッシュコードが存在します。つまり、equalsの実装に応じて均等とみなされる点がたくさんあることを意味します。


またStringsObjects.hashで作成したハッシュのハッシュ衝突の上につまずき誰かのために、この例equals and hashCode: Is Objects.hash method broken?を参照してください。

5

クラスの2つのインスタンスがお互いに等しいとみなされる基準を定義します。

ただし、searchId & productId性質が同じハッシュコードになる可能性があり、pageTrackingRequestの異なる組み合わせを検討すべきである、とあなたは等しくなどのさまざまな組み合わせを検討する必要がない場合があります。 equalsは、3つのプロパティすべてがお互いに等しいことを要求するのがより理にかなっているかもしれません。

1

hashCodeをチェックするのではなく、プロパティ値を個別にチェックする必要があります。 2つの全く異なるobjectsの結果が同じではないhashCodeである可能性があります。

また、equalsは、hashCodeにのみ依存するべきではありません。 hashCode方法は、以下に変更されます場合:

@Override 
public int hashCode() 
{ 
    return 31; 
} 

equals方法はケースではありませんすべてのオブジェクトのtrueを返す開始します。

+0

...これは 'hashCode'のための完全な法的な実装です(しかし、もちろん非常に悪い)。 – Hulk

0

このアプローチは間違っています。ハッシュコードの等価性は、等しくないオブジェクトが同じハッシュを持つ可能性があるため、決定的なものではありません。これは設計されたバグです。

関連する問題