2

Java でequalsと hashCode をオーバーライドする際に考慮すべき問題は何ですか? getClass を使用して Java で適切な等価メソッドを記述し、同等とみなす 2 つのオブジェクトの RUntime 型を比較す​​る方法を詳細に説明しています。これを行う理由は、B が A を拡張する場合に a.equals(b) = b.equals(a) (再帰性) が必要であることを確認するためだと理解しています。

私の意見では、それは大きな制限を提供します。オブジェクト A のコレクションがある場合、それらは A のサブクラスであるため、いくつかの B オブジェクトを挿入すると、a.equals(b) は常に false になります...おそらく、特定の場合には、instanceofポリモーフィズムを提供するために古い演算子に固執する必要があります。サブタイプの平等を許可しますか? あなたの考えは何ですか?

4

2 に答える 2

4

インターフェイスだけを気にするように再定義されたjava.util場所の例を見るだけで十分です。.equals()たとえばjava.util.List、関連する特性の等価性が定義されており、ハッシュ コードを計算する式が明示的に文書化されています。

したがって、あなたの質問に答えるには、そうです - サブタイプを無視することは、特定の状況下では理にかなっています。しかし、インターフェイスを等価性の側面にするという、これに対する Josh Bloch のアプローチが気に入っています。

于 2012-08-06T15:31:08.917 に答える
1

必ずしもそうとは限りません。たとえば、JDK のコレクションを見ると、等価性の定義がそれほど厳密ではありません。以下のコードは、「true」を 2 回出力します。最終的には、契約と文書の問題です。

equalsリストの契約(強調鉱山):

指定されたオブジェクトがこのリストと等しいかどうかを比較します。指定されたオブジェクトもリストであり、両方のリストが同じサイズであり、2 つのリスト内の対応する要素のすべてのペアが等しい場合にのみ、true を返します。(2 つの要素 e1 と e2 は、(e1==null ? e2==null : e1.equals(e2)) の場合に等しいです。) つまり、2 つのリストは、同じ要素が同じ順序で含まれている場合に等しいと定義されます。 . この定義により、List インターフェースのさまざまな実装で equals メソッドが適切に機能することが保証されます。

実装するすべてのクラスがListそのコントラクトを尊重する限り、再帰性の要件に違反しないことに注意してください。

public static void main(String[] args) {
    List<String> list1 = new ArrayList<String>();
    list1.add("a");

    List<String> list2 = new LinkedList<String>();
    list2.add("a");

    List<String> list3 = Arrays.asList("a");

    System.out.println("arraylist = linkedlist? " + list1.equals(list2));
    System.out.println("arraylist = Arrays.aslit? " + list1.equals(list3));
}
于 2012-08-06T15:31:42.240 に答える