[java] Java의 Enum final에 compareTo가있는 이유는 무엇입니까?

Java의 열거 형은 Comparable인터페이스를 구현합니다 . ComparablecompareTo메서드 를 재정의하는 것이 좋지만 여기서는 최종적으로 표시됩니다. 의 기본 자연 질서 Enum의는 compareTo나열된 순서입니다.

Java 열거 형에 이러한 제한이있는 이유를 아는 사람이 있습니까?



답변

일관성을 위해 … enum유형을 보면 자연스러운 순서가 상수가 선언되는 순서 라는 사실 을 알 수 있습니다.

이 문제를 해결하려면 쉽게 직접 만들고 Comparator<MyEnum>다른 주문이 필요할 때마다 사용할 수 있습니다 .

enum MyEnum
{
    DOG("woof"),
    CAT("meow");

    String sound;
    MyEnum(String s) { sound = s; }
}

class MyEnumComparator implements Comparator<MyEnum>
{
    public int compare(MyEnum o1, MyEnum o2)
    {
        return -o1.compareTo(o2); // this flips the order
        return o1.sound.length() - o2.sound.length(); // this compares length
    }
}

다음을 Comparator직접 사용할 수 있습니다 .

MyEnumComparator c = new MyEnumComparator();
int order = c.compare(MyEnum.CAT, MyEnum.DOG);

또는 컬렉션 또는 배열에서 사용하십시오.

NavigableSet<MyEnum> set = new TreeSet<MyEnum>(c);
MyEnum[] array = MyEnum.values();
Arrays.sort(array, c);

추가 정보 :


답변

소스 코드 순서를 사용하는 compareTo의 기본 구현을 제공하는 것은 괜찮습니다. 최종화는 썬의 실수였습니다. 서수는 이미 선언 순서를 설명합니다. 대부분의 상황에서 개발자는 논리적으로 요소를 정렬 할 수 있지만 때로는 가독성과 유지 관리를 가장 중요하게 만드는 방식으로 구성된 소스 코드를 원합니다. 예를 들면 :


  //===== SI BYTES (10^n) =====//

  /** 1,000 bytes. */ KILOBYTE (false, true,  3, "kB"),
  /** 106 bytes. */   MEGABYTE (false, true,  6, "MB"),
  /** 109 bytes. */   GIGABYTE (false, true,  9, "GB"),
  /** 1012 bytes. */  TERABYTE (false, true, 12, "TB"),
  /** 1015 bytes. */  PETABYTE (false, true, 15, "PB"),
  /** 1018 bytes. */  EXABYTE  (false, true, 18, "EB"),
  /** 1021 bytes. */  ZETTABYTE(false, true, 21, "ZB"),
  /** 1024 bytes. */  YOTTABYTE(false, true, 24, "YB"),

  //===== IEC BYTES (2^n) =====//

  /** 1,024 bytes. */ KIBIBYTE(false, false, 10, "KiB"),
  /** 220 bytes. */   MEBIBYTE(false, false, 20, "MiB"),
  /** 230 bytes. */   GIBIBYTE(false, false, 30, "GiB"),
  /** 240 bytes. */   TEBIBYTE(false, false, 40, "TiB"),
  /** 250 bytes. */   PEBIBYTE(false, false, 50, "PiB"),
  /** 260 bytes. */   EXBIBYTE(false, false, 60, "EiB"),
  /** 270 bytes. */   ZEBIBYTE(false, false, 70, "ZiB"),
  /** 280 bytes. */   YOBIBYTE(false, false, 80, "YiB");

위의 순서는 소스 코드에서 좋아 보이지만 작성자가 compareTo가 작동해야한다고 생각하는 방식은 아닙니다. 원하는 compareTo 동작은 바이트 수를 기준으로 정렬하는 것입니다. 그렇게하는 소스 코드 순서는 코드의 구성을 저하시킵니다.

열거 형의 클라이언트로서 저자가 소스 코드를 어떻게 구성했는지는 신경 쓰지 않았습니다. 나는 그들의 비교 알고리즘이 어떤 종류의 이해를 원합니다. Sun은 불필요하게 소스 코드 작성자를 바인드했습니다.


답변

열거 형 값은 선언 된 순서에 따라 논리적으로 정확하게 정렬됩니다. 이것은 Java 언어 사양의 일부입니다. 따라서 열거 형 값은 동일한 Enum의 구성원 인 경우에만 비교할 수 있습니다. 스펙은 compareTo ()에 의해 반환 된 비교 가능한 순서가 값이 선언 된 순서와 동일하다는 것을 추가로 보장하려고합니다. 이것이 바로 열거 형의 정의입니다.


답변

한 가지 가능한 설명은와 compareTo일치해야한다는 것입니다 equals.

그리고 equals열거 형은 동일성 ( ==) 과 일치해야합니다 .

경우 compareTo가 아닌 마지막으로 곳에는 일치하지 않았다 행동으로 재정의 할 수있을 것이다 equals매우 직관적 것입니다.


답변

열거 형 요소의 자연스러운 순서를 변경하려면 소스 코드에서 순서를 변경하십시오.


답변