Frage

Ein Enum in Java implementiert die Comparable Schnittstelle. Es wäre schön gewesen, Comparable die compareTo Methode außer Kraft zu setzen, aber hier ist es als final markiert. Der Standard natürliche Ordnung auf Enum des compareTo ist die angegebene Reihenfolge.

Wer weiß, warum eine Java Aufzählung diese Einschränkung hat?

War es hilfreich?

Lösung

Für Konsistenz Ich denke ..., wenn Sie eine enum Art sehen, wissen Sie für eine Tatsache, , dass seine natürliche Ordnung ist die Reihenfolge, in der die Konstanten deklariert werden.

Um dies zu umgehen, können Sie einfach Ihre eigene Comparator<MyEnum> erstellen und verwenden, wenn Sie eine andere Bestellung benötigen:

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

Sie können die Comparator direkt verwenden:

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

oder verwenden Sie es in einer Sammlung oder Arrays:

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

Weitere Informationen:

Andere Tipps

Die Bereitstellung einer Standardimplementierung von compareTo, die den Quellcode Ordnung verwendet, ist in Ordnung; so dass es ein Fehltritt von Sun Teil endgültig wurde. Die Ordnungs machen bereits die Reihenfolge der Deklaration. Ich bin damit einverstanden, dass ein Entwickler in den meisten Situationen kann nur logisch ihre Elemente bestellen, aber manchmal will man den Source-Code in eine Weise organisiert, die als größte Lesbarkeit und Wartung macht. Zum Beispiel:


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

Die obige Reihenfolge sieht im Quellcode gut, ist aber nicht, wie der Autor glaubt, soll die compareTo arbeiten. Das gewünschte Verhalten ist compareTo der Bestellung durch Anzahl von Bytes sein. Die Sourcecode-Bestellung, die das passieren würde, verschlechtert die Organisation des Codes.

Als Kunde einer Aufzählung könnte ich nicht weniger interessieren, wie der Autor ihren Quellcode organisiert. Ich will ihre Vergleichsalgorithmus eine Art von Sinn machen, wenn. Sun hat unnötig Quellcode Autoren in einer Bindung setzen.

Aufzählungswerte sind logisch genau geordnet nach der Reihenfolge, wie sie deklariert sind. Dies ist Teil der Java-Sprachspezifikation. Daraus folgt, dass Enumerationswerte können nur verglichen werden, wenn sie Mitglieder derselben Enum sind. Die Spezifikation will weiter gewährleisten, dass die vergleichbare Größenordnung wie von compareTo () zurück ist das gleiche wie die Reihenfolge, in der die Wert deklariert wurden. Dies ist die Definition einer Aufzählung.

Eine mögliche Erklärung ist, dass compareTo mit equals konsistent sein sollte.

Und equals für Aufzählungen sollte mit Identität Gleichheit (==) im Einklang steht.

Wenn compareTo wo nicht endgültig zu sein, um es möglich wäre es mit einem Verhalten außer Kraft zu setzen, die mit equals nicht übereinstimmte, was sehr wäre kontraintuitiv.

Wenn Sie die natürliche Reihenfolge der Enumeration der Elemente ändern, deren Reihenfolge in dem Source-Code ändern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top