.equals ()가 Java의 클래스에있는 동안 인터페이스에 .compareTo ()가있는 이유는 무엇입니까?


30

같은 인터페이스 가 클래스 에있는 동안 왜 인터페이스 .compareTo()에 있는지 알고 Comparable싶습니다 . 나에게, 왜 같은 방법 이 클래스 에 없는지 임의적 인 것처럼 보입니다 ..equalsObject.compareTo()Object

사용하려면 .compareTo(), 당신은 구현 Comparable인터페이스와 구현 .compareTo()당신의 목적을 위해 방법을. 를 들어 .equals()모든 클래스가 상속하기 때문에 방법, 당신은 단순히 당신의 클래스의 메소드를 오버라이드 (override) Object클래스입니다.

내 질문은 왜 같은 .compareTo()클래스가 아닌 구현하는 인터페이스 와 같은 메소드 Object입니까? 마찬가지로 .equals()클래스 의 메소드 는 왜 Object구현되고 일부 인터페이스에서는 구현되지 않습니까?



2
Java 언어의 디자인 선택입니다. 반드시 올바른 선택이라고 할 필요는 없습니다. Haskell 과 같은 다른 언어에서는 값 평등을 얻기 위해 평등 인터페이스구현 해야합니다 (실제로는 유형 Eq클래스에 인스턴스를 제공합니다 ).
mucaho

답변:


58

모든 객체를 비교할 수는 없지만 모든 객체가 동일한 지 확인할 수 있습니다. 다른 것이 없다면, 두 객체가 메모리의 동일한 위치에 있는지 확인할 수 있습니다 (참조 평등).

compareTo()Thread개체 에서 무엇을 의미 합니까? 하나의 스레드가 다른 스레드보다 "더 큰"방법은 무엇입니까? 두 ArrayList<T>s를 어떻게 비교 합니까?

Object계약에 적용 하는 모든 자바 클래스. 하나의 클래스 만 자체 클래스의 다른 인스턴스와 비교할 Object수없는 경우 인터페이스의 일부가되도록 요구할 수 없습니다.

Joshua Bloch는 클래스가 구현하기를 원하는 이유를 설명 할 때 "자연 순서"라는 핵심 단어를 사용합니다 Comparable. 나는 내 위의 예에서 언급하지 모든 클래스는 그래서 모든 클래스가 구현해야하지, 자연적인 순서를 가지고 Comparable도한다 ObjectcompareTo방법을.

...에 compareTo메소드가 선언되어 있지 않습니다 Object. ... 단순한 평등 비교 외에 순서 비교를 허용한다는 점을 제외하고는 Objectequals방법 과 문자가 비슷하며 일반적입니다. 구현함으로써 Comparable클래스는 해당 인스턴스가 자연스러운 순서를 가지고 있음을 나타냅니다 .

효과적인 자바, 제 2 판 : Joshua Bloch. 타원은 다른 장과 코드 예제에 대한 참조를 제거합니다.

자연스러운 순서가없는 클래스가 아닌 클래스 에 순서 를 적용 하려는 경우 정렬을 돕기 위해 Comparable항상 Comparator인스턴스를 제공 할 수 있습니다 .


3
compareTo with Exception (추상 클래스가 아니므로 aNullPointerException.compareTo (anUnsupportedFlavorException)은 다음과 같은 의미를 갖도록 구현했을 것입니다.

10
모든 객체가 동일한 지 검사 할 수 있습니다 . Java에서는 가능하지만 일반적으로 no입니다. 등식 비교가 이해되지 않는 객체의 예가 있습니다 (예 : 단일성 등). ValueEquality 및 ReferenceEquality와 같은 인터페이스 (추상 클래스)가있을 수 있습니다. 그것은 그렇게 나쁜 생각이 아닐 수도 있습니다 ...
qbd

5
"모든 객체가 동일한 지 검사 할 수있다. 다른 것이 없다면, 두 객체가 메모리의 동일한 위치에 존재하는지 확인할 수있다 (참조 동등성)." 우리는 ==후자를 가지고 있기 때문에 이것에 중공 고리가 있습니다. 중복 기본값을 무시하면 모든 유형이 동등성 관계를 지원하지 않을 수 있기 때문에 모든 클래스에서 가정 하지 않는 유효한 이유를 찾을 수 있습니다 equals.
Raphael

3
동등성을 정의 할 수없는 유형의 두 가지 예 : 스트림 (예 : 게으른 잠재적 무한 목록 또는 무한 정밀도 숫자) 및 함수. 전자는 평등을 확립하기 위해서는 무한히 비교할 필요가 있다는 문제가있다. 두 기능이 동일한 지 여부를 결정할 수 없습니다. 이러한 유형의 두 인스턴스가 동일한 메모리 위치에 존재하는지 묻는 것은 1)별로 유용하지 않으며 2) 클라이언트가 구현 세부 사항에 민감한 코드를 작성할 수 있습니다. 오늘은 여러분이 요청할 때마다 동일한 무한 목록의 새로운 인스턴스를 줄 수 있습니다. 내일 나는 그것을 기억할 수 있습니다.
Doval

6
@Snowman 구현 세부 사항을 노출한다는 사실과 쓸모가 없다는 사실은 그것을 허용 할 수없는 충분한 이유입니다. Java 8의 모든 "값 기반"클래스에는 "클래스를 ==인스턴스화하는 방법이 구현 세부 사항이지만 언어를 사용하여 숨길 수 없기 때문에" 사용하는 경우 어떻게되는지에 대해 책임지지 않습니다 "라는 상용구 가 있습니다. 두 Integers를 참조로 비교하는 사람 은 바보라고 할 수 있지만 비교를 시작하는 것은 여전히 ​​어리 석습니다.
Doval

8

§4.3.2 JLS 정의 class다음과 같은 방법으로 개체를 :

4.3.2. 클래스 객체

이 클래스 Object는 다른 모든 클래스의 수퍼 클래스 (§8.1.4)입니다.

모든 클래스 및 배열 유형은 class의 메소드를 상속 (§8.4.8) Object하며 다음과 같이 요약됩니다.

  • 이 방법 clone은 객체를 복제하는 데 사용됩니다.

  • 이 방법 equals은 참조가 아닌 값을 기준으로하는 객체 평등 개념을 정의합니다.

  • 이 방법 finalize은 객체가 파괴되기 직전에 실행됩니다 (§12.6).

  • 이 메소드 getClass는 객체의 클래스를 나타내는 Class 객체를 반환합니다.

  • Class목적은 각각의 기준 입력에 대한 필요성이 존재한다. 예를 들어 클래스의 정규화 된 이름, 해당 멤버, 직속 슈퍼 클래스 및 구현하는 인터페이스를 검색하는 데 사용할 수 있습니다.

    메소드 호출 표현식의 유형 getClassClass<? extends |T|>에서 T검색되는 클래스 또는 인터페이스 (§15.12.1)입니다 getClass.

    선언 된 클래스 메소드 synchronized(§8.4.3.6)는 클래스의 클래스 오브젝트와 연관된 모니터에서 동기화됩니다.

  • 이 방법 hashCode은 등식과 함께 해시 테이블과 같이 매우 유용합니다 java.util.Hashmap.

  • 상기 방법은 wait, notify그리고 notifyAll병행하여 프로그램 스레드 (§17.2)에 사용된다.

  • 이 메소드 toString는 객체의 문자열 표현을 반환합니다.

그래서 그 이유 equalsObject있지만 compareTo별도의 인터페이스에 있습니다. 나는 그들이 Object가능한 한 최소한으로 유지하기를 원했다고 추측 합니다. 그들은 아마도 거의 모든 Objects 것이 필요 equals하고 hashCode(실제로 평등 테스트의 한 형태 일뿐) 모든 객체가 ordering 개념을 가질 필요는 없다는 것을 알았 compareTo습니다.


이론적으로 인터페이스가있을 수 Equitable<T>있지만 인터페이스를 Object구현하면 모든 클래스는 Equitable<Object>입니다. 그 시점에 차이가 있습니까? 실제로 실제로는 복잡하지 않습니다.
Captain Man

1
@CaptainMan .Net object에는 Equals(object)Java와 마찬가지로가 있지만 IEquatable<T>인터페이스 도 있습니다. 그것이 존재하는 주된 이유 T는 값 유형이 when 일 때 boxing을 피하는 것이기 때문에 Java에서는 불가능합니다.
svick

hashCode는 해시 충돌이 있기 때문에 평등 테스트 형식 이 아닙니다 . A와 B가 같으면 동일한 hashCode를 갖지만 A와 B가 같은 hashCode를 가지고 있다고해서 이것이 같다는 것은 아닙니다!
Josef

실제로, 당신의 대답은 더 오래된 JLS ( titanium.cs.berkeley.edu/doc/java-langspec-1.0.pdf )로 전환하면 큰 이점을 얻을 것입니다 - 직접 equals선언 된 이유에 대해 훨씬 더 좋은 인용문 이 Object있습니다 : The methods equals and hashCode are declared for the benefit of hashtables such as java.util.Hashtable (§21.7)-Java 디자인으로 이전 버전과 호환되며 Java 1.0 디자인 선택이 실제로 equals존재하는 이유 입니다.
vaxquis 12

내가 제안한 편집 내용은 "너무 과감한"것으로 거부 될 수 있습니다. 관련 항목을 Ctrl + C / Ctrl + V로 대답하려면 pastebin.com/8c4EpLRX
vaxquis

2

눈사람의 탁월한 답변 외에도 Comparable오랫동안 일반적인 인터페이스였습니다. 유형은 구현하지 않고 자체 유형이있는 곳 compareTo(object)을 구현 합니다. 이 클래스에서 파생 된 클래스를 모르기 때문에에 구현할 수 없습니다 .compareTo(T)Tobjectobject

objectcompareTo(object)메소드를 정의 할 수 있었지만 이것은 눈사람이 지적한 것, 두 개 ArrayList<T>또는 두 개 Thread사이의 비교뿐만 아니라 an ArrayList<T>과 a 사이의 비교도 가능하게 할 것 Thread입니다. 더 무의미합니다.


0

두 개의 객체 참조가 있다고 가정합니다. X는 String"George"컨텐츠 를 보유 하는 인스턴스를 식별합니다 . Y Point는 좌표 를 보유한 사례를 식별한다 [12,34]. 다음 두 가지 질문을 고려하십시오.

  • X와 Y는 동등한 객체를 식별합니까?

  • X는 Y 이전, 이후 또는 Y와 동일해야합니까?

X와 Y가 관련되지 않은 유형의 인스턴스를 식별한다는 사실은 첫 번째 질문을 고려할 때 아무런 문제가 없습니다. 객체 유형이 객체를 동등한 것으로 정의하는 공통 기반을 공유하는 경우에만 객체를 동등한 것으로 간주 할 수 있습니다. 이후 String및 것은 Point이러한 기본 (유일한 공통 기본 타입이 아닌 동등한 모든 다른 오브젝트에 관해서) 대답은 간단하게 "아니오"입니다이 없습니다.

그러나 유형이 관련이 없다는 사실은 두 번째 질문과 관련하여 큰 문제를 제기합니다. 일부 유형은 자신의 인스턴스 간의 순서 관계를 정의하고, 어떤 순서 관계도 여러 유형에 걸쳐 연장 할 수있다 [예를 들면 것이 가능할 것이다 BigIntegerBigDecimal두 유형의 인스턴스가 다른 인스턴스에 상대적으로 순위가 될 수 있도록 할 비교 방법을 정의하는,하지만 일반적으로 두 개의 임의의 인스턴스를 가져 와서 "X가 Y 이전에, 이후에 또는 Y와 동등해야합니까?"라고 묻고 전체 순서를 도출하는 것은 불가능합니다. 객체가 전체가 아닌 일관된 순서 를보고해야하는 경우 "Y와 관련하여 X를 정렬, 후행, 동등 또는 비 등급 화해야합니까?"라고 물을 수 있습니다.하나, 그러나 대부분의 정렬 알고리즘에는 총 순서가 필요합니다. 따라서 compareTo"unranked"가 유효한 반환 인 경우 모든 객체가 메서드를 구현할 수 있더라도 이러한 메서드는 해당 개체 의 존재를 정당화하는 데 유용하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.