Why is compareTo on an Enum final in Java?

Viewed 74933

An enum in Java implements the Comparable interface. It would have been nice to override Comparable's compareTo method, but here it's marked as final. The default natural order on Enum's compareTo is the listed order.

Does anyone know why a Java enums have this restriction?

5 Answers

For consistency I guess... when you see an enum type, you know for a fact that its natural ordering is the order in which the constants are declared.

To workaround this, you can easily create your own Comparator<MyEnum> and use it whenever you need a different ordering:

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
    }
}

You can use the Comparator directly:

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

or use it in collections or arrays:

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

Further information:

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.

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

Related