Pregunta

Una enumeración en Java implementa el Comparable interfaz.Hubiera sido bueno anular Comparable's compareTo método, pero aquí está marcado como final.El orden natural predeterminado en Enum's compareTo es el orden listado.

¿Alguien sabe por qué las enumeraciones de Java tienen esta restricción?

¿Fue útil?

Solución

Por coherencia supongo...cuando ves un enum tipo, ya sabes de hecho que su orden natural es el orden en que se declaran las constantes.

Para solucionar este problema, puedes crear fácilmente el tuyo propio. Comparator<MyEnum> y úsalo siempre que necesites un pedido diferente:

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

Puedes usar el Comparator directamente:

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

o usarlo en colecciones o matrices:

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

Más información:

Otros consejos

Proporcionar una implementación por defecto de compareTo que utiliza el código fuente de pedidos está bien; por lo que es final fue un paso en falso por parte del solar. El ordinal ya representa el orden de la declaración. Estoy de acuerdo que en la mayoría de situaciones, un desarrollador puede simplemente ordenar lógicamente sus elementos, pero a veces uno quiere que el código fuente organizada de una manera que hace que la legibilidad y mantenimiento sean de suma importancia. Por ejemplo:


  //===== 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");

El orden de arriba se ve bien en el código fuente, pero no es la forma en que el autor cree que el compareTo debería funcionar. El comportamiento compareTo deseada es tener pedido sea por número de bytes. El orden del código fuente que hacer que eso suceda degrada la organización del código.

Como cliente de una enumeración que no podría cuidar menos cómo el autor organiza su código fuente. Yo quiero su algoritmo de comparación para hacer algún tipo de sentido, sin embargo. Sun ha puesto innecesariamente escritores de código fuente en un aprieto.

Los valores de enumeración se ordenan lógicamente, precisamente, de acuerdo con el orden en que se declaran. Esto es parte de la especificación del lenguaje Java. Por lo tanto se deduce que los valores de enumeración sólo pueden compararse si son miembros de la misma enumeración. La especificación quiere garantizar, además, que el orden comparable como devuelto por compareTo () es el mismo que el orden en que fueron declarados los valores. Esta es la definición misma de una enumeración.

Una posible explicación es que compareTo debe ser coherente con equals.

Y == para enumeraciones debe ser coherente con la igualdad de identidad (<=>).

Si <=> donde ser no final sería posible anular con un comportamiento que no era compatible con <=>, lo que sería muy contrario a la intuición.

Si desea cambiar el orden natural de los elementos de su enumeración, cambiar su orden en el código fuente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top