この比較/equals/hashcodeの実装について心配する必要がありますか?
-
30-09-2019 - |
質問
私はQAの真っin中にあり、開発者が同等の実装を実装するDTOを持っているいくつかのインスタンスを見つけました。このDTOには7つまたは8つのフィールドがあります。比較方法は、1つのフィールドにのみ実装されています。
private DateMidnight field1; //from Joda date/time library
public int compareTo(SomeObject o) {
if (o == null) {
return -1;
}
return field1.compareTo(o.getField1());
}
同様に、Equalsメソッドはオーバーライドされ、基本的には次のようになります。
return field1.equals(o.getField1());
そして最後に、ハッシュコードメソッドの実装は次のとおりです。
return field1.hashCode;
field1
決してnullであってはならず、これらのオブジェクト全体で一意になります(つまり、同じオブジェクトを2つのオブジェクトを取得しないでください field1
).
それで、実装は一貫していますが、これは良いことですが、1つのフィールドのみが使用されていることを心配する必要がありますか?これは珍しいですか?問題を引き起こしたり、他の開発者を混乱させる可能性がありますか?これらのオブジェクトのリストが渡され、別の開発者がソムソートのマップまたはセットを使用し、これらのオブジェクトから異常な動作を取得するシナリオを考えています。どんな考えも感謝しています。ありがとう!
解決
これは「First Use Wins」のケースであると思われます。誰かがこれらのオブジェクトのコレクションを並べ替えたり、ハッシュマップに入れたりする必要があり、 彼ら 日付だけを気にかけました。オーバーライドすることであった最も簡単な実装方法 equals
/hashCode
実装します Comparable<T>
あなたが言った方法で。
スペシャリストの並べ替えの場合、より良いアプローチは実装することです Comparator<T>
別のクラスで...しかし、Javaには、残念ながら、平等テストに相当するクラスがありません。正直に言うと、Javaコレクションの大きな弱点だと思います。
これを本当に仮定しています そうではありません 「1つの自然で明白な比較」、それは確かにデザインの点で匂いがします...そして非常に慎重に文書化する必要があります。
他のヒント
厳密に言えば、これは同等の仕様に違反します。
http://download.oracle.com/javase/6/docs/api/java/lang/comparable.html
nullはクラスのインスタンスではなく、e.compareTo(null)は、e.equals(null)がfalseを返す場合でもnullpointerexceptionをスローする必要があることに注意してください。
同様に、それは次のように見えます equals
メソッドはNPEをオンにします equals(null)
戻る代わりに false
(もちろん、ヌル処理コードを「煮詰めた」場合を除きます)。
問題を引き起こしたり、他の開発者を混乱させる可能性がありますか?
おそらく、そうではありません。それは本当にあなたのプロジェクトの大きさと、あなたのオブジェクトソースコードが使用されると予想される広範囲/「再利用可能」/長寿命に依存します:
- 小/短命/限られた使用==おそらく問題ではありません。
- 大型/長寿命/広範囲の使用==直感に反する実装は将来の問題を引き起こす可能性があります
field1が 本当にユニーク. 。そうでない場合は、問題がある可能性があります。とにかく、私のアドバイスはいくつかのユニットテストを行うことです。彼らは真実を示すべきです。
心配する必要はないと思います。 3つの方法の間の契約は保持され、一貫しています。
それかどうか 正しい ビジネスロジックからの観点からは、別の質問があります。
EG Field1がデータベース内の主キーにマップする場合、それは完全に有効です。 Field1が人の「最初の名前」である場合、私は心配しています