developer tip

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

optionbox 2020. 9. 14. 08:18
반응형

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 동작은 바이트 수를 기준으로 정렬하는 것입니다. 그렇게하는 소스 코드 순서는 코드의 구성을 저하시킵니다.

As a client of an enumeration i could not care less how the author organized their source code. I do want their comparison algorithm to make some kind of sense, though. Sun has unnecessarily put source code writers in a bind.


Enumeration values are precisely ordered logically according to the order they are declared. This is part of the Java language specification. Therefore it follows that enumeration values can only be compared if they are members of the same Enum. The specification wants to further guarantee that the comparable order as returned by compareTo() is the same as the order in which the values were declared. This is the very definition of an enumeration.


One possible explanation is that compareTo should be consistent with equals.

And equals for enums should be consistent with identity equality (==).

If compareTo where to be non-final it would be possible to override it with a behaviour which was not consistent with equals, which would be very counter-intuitive.


If you want to change the natural order of your enum’s elements, change their order in the source code.

참고URL : https://stackoverflow.com/questions/519788/why-is-compareto-on-an-enum-final-in-java

반응형