(Java) 추가 값 요소의 클래스를 계승하는 equals () 실현 방법
11061 단어 Java
개시하다
만약 상기 상속관계의 유형인 equals() 방법만 일반적으로 실시한다면 equals()는 만족해야 할 성질을 만족시킬 수 없다.이것은 모두가 다 알고 있는 것이다(보충1)
이 참고 문헌에도 회피 전략이 기재되어 있다.별문헌.를 참고하십시오.
*1 참조
결론
다음 2 매개변수의 equals() 정적 방법을 작성하여 Object를 통과합니다.equals()를 호출합니다.중요한 것은 두 종류의 equals () 부분을 호출하는 것이다.이것은 이 종류 이외에도 사용할 수 있다(보충2)
참고로 표준 API에는 Objects가 있습니다.equals(Object, Object)가 있지만 왼쪽 equals()만 호출됩니다.
ObjectUtil.javafinal class ObjectUtil {
private ObjectUtil() { throw new AssertionError("Not intended to be instanciated"); }
public static boolean equals(final Object lhs, final Object rhs) {
// 左辺・右辺の参照先が同じなら同一
if (lhs == rhs) return true;
// 左辺・右辺の参照先が共にnullなら同一
if (lhs == null && rhs == null) return true;
// 左辺・右辺の参照先のどちらかがnullなら不同
if (lhs == null || rhs == null) return false;
// 左辺・右辺の参照先が同一クラスならそのクラスのequals()を返却する
if (lhs.getClass() == rhs.getClass()) return lhs.equals(rhs);
// 左辺・右辺の参照先が別のクラスなら両クラスのequals()のandを返却する
return lhs.equals(rhs) && rhs.equals(lhs);
}
}
보충1 // 1. 対称性が満たせない
// -> 右辺・左辺を入れ替えると結果が異なる
// 上図のクラス構成を用いた例
Point1D p1 = new Point1D(0);
Point2D p2 = new Point2D(0, 0);
assert(p1.equals(p2) == true); // x値しか比較しないためtrue
assert(p2.equals(p1) == false); // Point2Dのinstanceであることを判定するためfalse
// 2. 推移性が満たせない
// -> p1 == p2 && p2 == p3 の場合でも、p1 == p3 とならない
// 上図のクラス構成を用いた例
// 前提: Point2D.equals() 仕様に下記を追加しておく
// 引数が、Point1Dまたはそのサブクラス、かつx値が同じ場合でも、true
Point2D p1 = new Point2D(0, 0);
Point1D p2 = new Point1D(0);
Point2D p3 = new Point2D(0, 1);
assert(p1.equals(p2) == true); // 新仕様のためtrue
assert(p2.equals(p3) == true); // x値の比較しないためtrue
assert(p1.equals(p3) == false); // x,y値を比較するためfalse
// 3. リスコフの置換原則が満たせない
// -> サブクラスでも同様の動きが想定されるが、そうならない
// 上図のクラス構成を用いた例
// 前提1: Point1D.equals() 仕様を下記のように変更する
// 引数が、Point1D、かつx値が同じ場合のみ、true
// 前提2: CountingPoint1D.equals() 仕様を下記のように変更する
// 引数が、CountingPoint1D、かつx値が同じ場合のみ、true
Point1D p1 = new Point(0);
CountingPoint1D cp1 = new CountingPoint(0);
CountingPoint1D cp2 = new CountingPoint(0);
List<CountingPoint1D> list = Arrays.asList(cp1);
assert(list.contains(cp2) == true); // cp1 == cp2 のためtrue
assert(list.contains(p1) == false); // 前提1のためfalse
보충2 // 継承ではなくコンポジションを用いる
// 例
class Point2D {
private final Point1D p1;
private final int y;
...
@Override
public boolean equals(Object o) {
if (!(o instanceof Point2D)) return false;
Point2D rhs = (Point2D)o;
return p1.equals(rhs.p1) && y.equals(rhs.y);
}
}
*1
조시르 부크(평성 26년)'Effective Java 제2판'완선.프로젝트 8
*2
안드레 알렉산더(2013)'프로그래밍 언어 D'수영회사.6.8.3
Reference
이 문제에 관하여((Java) 추가 값 요소의 클래스를 계승하는 equals () 실현 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/washikawau/items/0b1864b6dedd46db5070
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
다음 2 매개변수의 equals() 정적 방법을 작성하여 Object를 통과합니다.equals()를 호출합니다.중요한 것은 두 종류의 equals () 부분을 호출하는 것이다.이것은 이 종류 이외에도 사용할 수 있다(보충2)
참고로 표준 API에는 Objects가 있습니다.equals(Object, Object)가 있지만 왼쪽 equals()만 호출됩니다.
ObjectUtil.java
final class ObjectUtil {
private ObjectUtil() { throw new AssertionError("Not intended to be instanciated"); }
public static boolean equals(final Object lhs, final Object rhs) {
// 左辺・右辺の参照先が同じなら同一
if (lhs == rhs) return true;
// 左辺・右辺の参照先が共にnullなら同一
if (lhs == null && rhs == null) return true;
// 左辺・右辺の参照先のどちらかがnullなら不同
if (lhs == null || rhs == null) return false;
// 左辺・右辺の参照先が同一クラスならそのクラスのequals()を返却する
if (lhs.getClass() == rhs.getClass()) return lhs.equals(rhs);
// 左辺・右辺の参照先が別のクラスなら両クラスのequals()のandを返却する
return lhs.equals(rhs) && rhs.equals(lhs);
}
}
보충1 // 1. 対称性が満たせない
// -> 右辺・左辺を入れ替えると結果が異なる
// 上図のクラス構成を用いた例
Point1D p1 = new Point1D(0);
Point2D p2 = new Point2D(0, 0);
assert(p1.equals(p2) == true); // x値しか比較しないためtrue
assert(p2.equals(p1) == false); // Point2Dのinstanceであることを判定するためfalse
// 2. 推移性が満たせない
// -> p1 == p2 && p2 == p3 の場合でも、p1 == p3 とならない
// 上図のクラス構成を用いた例
// 前提: Point2D.equals() 仕様に下記を追加しておく
// 引数が、Point1Dまたはそのサブクラス、かつx値が同じ場合でも、true
Point2D p1 = new Point2D(0, 0);
Point1D p2 = new Point1D(0);
Point2D p3 = new Point2D(0, 1);
assert(p1.equals(p2) == true); // 新仕様のためtrue
assert(p2.equals(p3) == true); // x値の比較しないためtrue
assert(p1.equals(p3) == false); // x,y値を比較するためfalse
// 3. リスコフの置換原則が満たせない
// -> サブクラスでも同様の動きが想定されるが、そうならない
// 上図のクラス構成を用いた例
// 前提1: Point1D.equals() 仕様を下記のように変更する
// 引数が、Point1D、かつx値が同じ場合のみ、true
// 前提2: CountingPoint1D.equals() 仕様を下記のように変更する
// 引数が、CountingPoint1D、かつx値が同じ場合のみ、true
Point1D p1 = new Point(0);
CountingPoint1D cp1 = new CountingPoint(0);
CountingPoint1D cp2 = new CountingPoint(0);
List<CountingPoint1D> list = Arrays.asList(cp1);
assert(list.contains(cp2) == true); // cp1 == cp2 のためtrue
assert(list.contains(p1) == false); // 前提1のためfalse
보충2 // 継承ではなくコンポジションを用いる
// 例
class Point2D {
private final Point1D p1;
private final int y;
...
@Override
public boolean equals(Object o) {
if (!(o instanceof Point2D)) return false;
Point2D rhs = (Point2D)o;
return p1.equals(rhs.p1) && y.equals(rhs.y);
}
}
*1
조시르 부크(평성 26년)'Effective Java 제2판'완선.프로젝트 8
*2
안드레 알렉산더(2013)'프로그래밍 언어 D'수영회사.6.8.3
Reference
이 문제에 관하여((Java) 추가 값 요소의 클래스를 계승하는 equals () 실현 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/washikawau/items/0b1864b6dedd46db5070
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
// 1. 対称性が満たせない
// -> 右辺・左辺を入れ替えると結果が異なる
// 上図のクラス構成を用いた例
Point1D p1 = new Point1D(0);
Point2D p2 = new Point2D(0, 0);
assert(p1.equals(p2) == true); // x値しか比較しないためtrue
assert(p2.equals(p1) == false); // Point2Dのinstanceであることを判定するためfalse
// 2. 推移性が満たせない
// -> p1 == p2 && p2 == p3 の場合でも、p1 == p3 とならない
// 上図のクラス構成を用いた例
// 前提: Point2D.equals() 仕様に下記を追加しておく
// 引数が、Point1Dまたはそのサブクラス、かつx値が同じ場合でも、true
Point2D p1 = new Point2D(0, 0);
Point1D p2 = new Point1D(0);
Point2D p3 = new Point2D(0, 1);
assert(p1.equals(p2) == true); // 新仕様のためtrue
assert(p2.equals(p3) == true); // x値の比較しないためtrue
assert(p1.equals(p3) == false); // x,y値を比較するためfalse
// 3. リスコフの置換原則が満たせない
// -> サブクラスでも同様の動きが想定されるが、そうならない
// 上図のクラス構成を用いた例
// 前提1: Point1D.equals() 仕様を下記のように変更する
// 引数が、Point1D、かつx値が同じ場合のみ、true
// 前提2: CountingPoint1D.equals() 仕様を下記のように変更する
// 引数が、CountingPoint1D、かつx値が同じ場合のみ、true
Point1D p1 = new Point(0);
CountingPoint1D cp1 = new CountingPoint(0);
CountingPoint1D cp2 = new CountingPoint(0);
List<CountingPoint1D> list = Arrays.asList(cp1);
assert(list.contains(cp2) == true); // cp1 == cp2 のためtrue
assert(list.contains(p1) == false); // 前提1のためfalse
// 継承ではなくコンポジションを用いる
// 例
class Point2D {
private final Point1D p1;
private final int y;
...
@Override
public boolean equals(Object o) {
if (!(o instanceof Point2D)) return false;
Point2D rhs = (Point2D)o;
return p1.equals(rhs.p1) && y.equals(rhs.y);
}
}
*1조시르 부크(평성 26년)'Effective Java 제2판'완선.프로젝트 8
*2
안드레 알렉산더(2013)'프로그래밍 언어 D'수영회사.6.8.3
Reference
이 문제에 관하여((Java) 추가 값 요소의 클래스를 계승하는 equals () 실현 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/washikawau/items/0b1864b6dedd46db5070텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)