values - recorrer enum java
¿Por qué se comparaTo en una final de Enum en Java? (5)
Una enumeración en Java implementa la interfaz Comparable
. Habría sido bueno anular compareTo
método compareTo
Comparable
, pero aquí está marcado como final. El orden natural predeterminado en Enum
''s compareTo
es el orden listado.
¿Alguien sabe por qué una enumeración de Java tiene esta restricción?
Los valores de enumeración se ordenan con precisión lógicamente según 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 solo se pueden comparar si son miembros del mismo Enum. La especificación quiere garantizar aún más que el orden comparable devuelto por compareTo () sea el mismo que el orden en que se declararon los valores. Esta es la definición misma de una enumeración.
Por consistencia, supongo ... cuando ves un tipo de enum
, sabes con certeza que su ordenamiento natural es el orden en que se declaran las constantes.
Para solucionar este problema, puede crear fácilmente su propio Comparator<MyEnum>
y utilizarlo siempre que necesite 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
}
}
Puede 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:
Proporcionar una implementación predeterminada de compareTo que utiliza el orden de código fuente está bien; hacerlo final fue un paso en falso de parte de Sun. El ordinal ya cuenta para el orden de la declaración. Estoy de acuerdo en que, en la mayoría de las situaciones, un desarrollador puede simplemente ordenar lógicamente sus elementos, pero a veces uno quiere que el código fuente esté organizado de manera que la legibilidad y el mantenimiento sean primordiales. 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 anterior se ve bien en el código fuente, pero no es así como el autor cree que debería funcionar el compareTo. El comportamiento de comparación deseado es tener orden por número de bytes. El orden del código fuente que haría que eso suceda degrada la organización del código.
Como cliente de una enumeración, no me importa cómo el autor organizó su código fuente. Sin embargo, quiero que su algoritmo de comparación tenga algún sentido. Sun ha puesto innecesariamente escritores de código fuente en un aprieto.
Si desea cambiar el orden natural de los elementos de su enumeración, cambie su orden en el código fuente.
Una posible explicación es que compareTo
debe ser consistente con los equals
.
Y los equals
para las enumeraciones deben ser consistentes con la igualdad de identidad ( ==
).
Si compareTo
where ser no final, sería posible anularlo con un comportamiento que no era coherente con equals
, lo que sería muy contrario a la intuición.