特に対称プロパティを正しくするのは難しい(不可能?)からです。
classVehicle
と classがあるとしCar extends Vehicle
ます。引数も aであり、同じ重みを持つ場合にVehicle.equals()
生成されます。実装したい場合は、引数が車でもある場合にのみ生成する必要があり、重量を除いて、メーカー、エンジンなども比較する必要があります。true
Vehicle
Car.equals()
true
次のコードを想像してください。
Vehicle tank = new Vehicle();
Vehicle bus = new Car();
tank.equals(bus); //can be true
bus.equals(tank); //false
最初の比較はtrue
、偶然にもタンクとバスの重量が同じ場合に結果が出る可能性があります。しかし、タンクは車ではないため、車と比較すると常にfalse
.
いくつかの回避策があります。
厳密: 2 つのオブジェクトが等しいのは、それらがまったく同じ型 (およびすべてのプロパティが等しい) である場合に限られます。これは悪いことです。たとえば、サブクラス化して何らかの動作を追加したり、元のクラスを装飾したりする場合です。一部のフレームワークは、気付かないうちにクラスもサブクラス化しています (Hibernate、CGLIB プロキシを使用した Spring AOP...)。
Loose: 2 つのオブジェクトは、それらの型が「互換性があり」、内容が (意味的に) 同じである場合、同等です。HashSet
たとえば、同じ要素が含まれている場合、2 つのセットは等しいです。一方がそうで、もう一方がそうであるかどうかは問題ではありません(指摘してくれた@veerTreeSet
に感謝します)。
これは誤解を招く可能性があります。2 つLinkedHashSet
の s を取ります (コントラクトの一部として挿入順序が重要な場合)。ただし、equals()
生のSet
コントラクトのみが考慮されるtrue
ため、明らかに異なるオブジェクトに対しても比較が行われます。
Set<Integer> s1 = new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3));
Set<Integer> s2 = new LinkedHashSet<Integer>(Arrays.asList(3, 2, 1));
System.out.println(s1.equals(s2));