.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도한다 Object이 compareTo방법을.

...에 compareTo메소드가 선언되어 있지 않습니다 Object. ... 단순한 평등 비교 외에 순서 비교를 허용한다는 점을 제외하고는 Object의 equals방법 과 문자가 비슷하며 일반적입니다. 구현함으로써 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목적은 각각의 기준 입력에 대한 필요성이 존재한다. 예를 들어 클래스의 정규화 된 이름, 해당 멤버, 직속 슈퍼 클래스 및 구현하는 인터페이스를 검색하는 데 사용할 수 있습니다.

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

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

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

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

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

그래서 그 이유 equals는 Object있지만 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

object는 compareTo(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이러한 기본 (유일한 공통 기본 타입이 아닌 동등한 모든 다른 오브젝트에 관해서) 대답은 간단하게 "아니오"입니다이 없습니다.

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

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