Question

Un ENUM en Java implémente l'interface Comparable. Il aurait été agréable de passer outre la méthode est compareTo Enum, mais ici, il est marqué comme final. La valeur par défaut de l'ordre naturel de <=> 'est l'ordre <=> répertorié.

Est-ce que quelqu'un sait pourquoi un Java énumérations ont cette restriction?

Était-ce utile?

La solution

Par souci de cohérence, je suppose ... quand vous voyez un type de enum, vous savez pour un fait que son ordre naturel est l'ordre dans lequel les constantes sont déclarées.

Pour contourner ce problème, vous pouvez facilement créer votre propre et de l'utiliser Comparator<MyEnum> chaque fois que vous avez besoin d'un ordre différent:

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

Vous pouvez utiliser le directement Comparator:

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

ou l'utiliser dans des collections ou des tableaux:

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

Pour plus d'informations:

Autres conseils

Fournir une implémentation par défaut de compareTo qui utilise la commande code source est très bien; ce qui en fait un faux pas final a été de la part du Soleil. Le ordinale représente déjà l'ordre de déclaration. Je suis d'accord qu'un développeur peut simplement commander logiquement dans la plupart des situations de leurs éléments, mais parfois on veut que le code source organisée d'une manière qui rend la lisibilité et la maintenance d'être primordiale. Par exemple:


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

La commande ci-dessus semble bon dans le code source, mais pas comment l'auteur estime que le compareTo devrait fonctionner. Le comportement compareTo souhaité est d'avoir la commande soit par le nombre d'octets. La commande de code source qui y arriver dégrade l'organisation du code.

En tant que client d'une énumération je me fiche pas mal comment l'auteur a organisé leur code source. Je ne veux leur algorithme de comparaison pour faire une sorte de sens, cependant. Sun a inutilement mis écrivains de code source dans une impasse.

Les valeurs énumératives sont précisément commandées logiquement selon l'ordre dans lequel ils sont déclarés. Cela fait partie de la spécification du langage Java. Par conséquent, il en résulte que les valeurs d'énumération ne peuvent être comparés si elles sont membres de la même Enum. La spécification veut garantir en outre que l'ordre comparable retourné par compareTo () est le même que l'ordre dans lequel les valeurs ont été déclarées. Telle est la définition même d'une énumération.

Une explication possible est que devrait être compatible compareTo avec equals.

Et pour les énumérations devrait == être compatible avec l'égalité d'identité (<=>).

Si où être <=> non-finale, il serait possible de la remplacer par un comportement qui ne correspondait pas à <=>, ce qui serait très contre-intuitif.

Si vous voulez changer l'ordre naturel des éléments de votre ENUM, changer leur ordre dans le code source.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top