3

私は一連のコードの QA を行っている最中で、開発者が Comparable を実装する DTO を持っている例をいくつか見つけました。この DTO には、7 つまたは 8 つのフィールドがあります。compareTo メソッドは、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;

field1null になることはなく、これらのオブジェクト全体で一意になります (つまり、同じ を持つ 2 つのオブジェクトを取得するべきではありませんfield1)。

実装が一貫しているのは良いことですが、フィールドが 1 つしか使用されていないことに注意する必要がありますか? これは異常ですか?問題を引き起こしたり、他の開発者を混乱させたりする可能性はありますか? これらのオブジェクトのリストが渡され、別の開発者が何らかのマップまたはセットを使用して、これらのオブジェクトから異常な動作を取得するシナリオを考えています。どんな考えでも大歓迎です。ありがとう!

4

4 に答える 4

5

これは「先使い勝ち」のケースだと思います。誰かがこれらのオブジェクトのコレクションをソートしたり、ハッシュマップに入れたりする必要があり、日付だけを気にしていましたequalsそれを実装する最も簡単な方法は、 /をオーバーライドして、あなたが言った方法でhashCode実装することでした。Comparable<T>

スペシャリストのソートについてComparator<T>は、別のクラスで実装することをお勧めしますが、残念ながら、Java には等価性テストに相当するクラスがありません。正直に言うと、これは Java コレクションの大きな弱点だと思います。

これが「自然で明白な比較」ではないことを前提とすると、確かにデザインの面で匂いがします...そして非常に慎重に文書化する必要があります.

于 2010-12-03T08:03:59.253 に答える
2

厳密に言えば、これは Comparable 仕様に違反しています。

http://download.oracle.com/javase/6/docs/api/java/lang/Comparable.html

null はどのクラスのインスタンスでもないことに注意してください。e.equals(null) が false を返す場合でも、e.compareTo(null) は NullPointerException をスローする必要があります。

同様に、メソッドが戻る代わりにequalsNPE をスローするように見えます (もちろん、null 処理コードを「煮詰めた」場合を除きます)。equals(null)false

問題を引き起こしたり、他の開発者を混乱させたりする可能性はありますか?

おそらく、そうではない。それは、プロジェクトの規模と、オブジェクト ソース コードの使用が予想される範囲/「再利用可能」/長寿命に大きく依存します。

  • 小規模/短命/限定的な使用 == おそらく問題ありません。
  • 大規模/長寿命/広範な使用 == 直感に反する実装は、将来の問題を引き起こす可能性があります
于 2010-12-03T08:09:08.957 に答える
2

field1 が本当に一意である場合は、気にする必要はありません。そうでない場合は、問題が発生する可能性があります。とにかく、私のアドバイスは、いくつかの単体テストを行うことです。彼らは真実を示すべきです。

于 2010-12-03T08:24:09.687 に答える
1

気にする必要はないと思います。3 つのメソッド間の契約は維持され、一貫性があります。

ビジネス ロジックの観点から正しいかどうかは別の問題です。

たとえば、field1 がデータベースの主キーにマップされている場合、それは完全に有効です。field1 が人の「名」である場合、私は心配します

于 2010-12-03T08:05:18.567 に答える