Domanda

Un enum in Java implementa l'interfaccia di Comparable. Sarebbe stato bello per sovrascrivere il metodo s 'compareTo Enum, ma qui è contrassegnato come finale. L'impostazione predefinita ordine naturale su <=> <=> s 'è nell'ordine elencato.

Qualcuno sa il motivo per cui un enumerazioni Java hanno questa limitazione?

È stato utile?

Soluzione

Per coerenza immagino ... quando si vede un tipo enum, sai per un fatto che il suo ordinamento naturale è l'ordine in cui sono dichiarate le costanti.

Per risolvere questo, si può facilmente creare il proprio Comparator<MyEnum> e utilizzarlo ogni volta che avete bisogno di un ordine diverso:

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

È possibile utilizzare il Comparator direttamente:

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

o usarlo in collezioni o array:

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

Per ulteriori informazioni:

Altri suggerimenti

Fornire un'implementazione predefinita di compareTo che utilizza il codice sorgente di ordinazione è soddisfacente; rendendo finale è stato un passo falso da parte del sole. Il numero ordinale rappresenta già ordine di dichiarazione. Sono d'accordo che nella maggior parte delle situazioni di uno sviluppatore può solo logicamente ordinare i loro elementi, ma a volte si vuole il codice sorgente organizzato in un modo che rende la leggibilità e il mantenimento di essere di primaria importanza. Ad esempio:


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

È possibile che questo ordinamento guarda bene nel codice sorgente, ma non è come l'autore ritiene che il compareTo dovrebbe funzionare. Il comportamento compareTo desiderato è avere ordinamento sia per numero di byte. L'ordinamento codice sorgente che avrebbe fatto che questo accada degrada l'organizzazione del codice.

Come cliente di un'enumerazione non ho potuto importare di meno come l'autore ha organizzato il loro codice sorgente. Io voglio il loro algoritmo di confronto per fare una sorta di senso, però. Sun ha messo inutilmente scrittori di codice sorgente in un vicolo cieco.

valori di enumerazione sono proprio ordine logico secondo l'ordine in cui vengono dichiarati. Questa è parte della specifica del linguaggio Java. Pertanto ne consegue che valori di enumerazione possono essere confrontati solo se sono membri della stessa Enum. La specifica vuole garantire, inoltre, che l'ordine paragonabile restituita dalla compareTo () è lo stesso che l'ordine in cui sono stati dichiarati i valori. Questa è la definizione stessa di un'enumerazione.

Una possibile spiegazione è che compareTo devono essere coerenti con equals.

E == per enumerazioni dovrebbero essere coerenti con l'uguaglianza di identità (<=>).

Se <=> dove essere non finale sarebbe possibile sostituire con un comportamento che non era coerente con <=>, che sarebbe molto intuitivo.

Se si desidera cambiare l'ordine naturale degli elementi del vostro enum, modificarne l'ordine nel codice sorgente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top