Java 中的枚举实现了 Comparable 界面。覆盖就好了 ComparablecompareTo 方法,但这里它被标记为最终的。默认自然顺序 EnumcompareTo 是列出的顺序。

有谁知道为什么 Java 枚举有这个限制?

有帮助吗?

解决方案

为了保持一致性,我想...当你看到一个 enum 类型,你知道 事实上 它的自然顺序是声明常量的顺序。

要解决此问题,您可以轻松创建自己的 Comparator<MyEnum> 并在需要不同的排序时使用它:

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

您可以使用 Comparator 直接地:

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

或在集合或数组中使用它:

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

更多信息:

其他提示

提供的compareTo的默认实现,它使用源代码排序是细;使得它最终是在Sun的部分失误。序已经占申报顺序。我认为,在大多数情况下,开发者可以只是逻辑上订购他们的元素,但有时一个人想的方式,使可读性和维护是最重要的组织的源代码。例如:


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

在上述排序看源代码好,但笔者并不怎么认为的compareTo应该工作。所需的compareTo行为是有顺序是由字节数。源代码排序,将做到这一点降低了代码的组织。

作为枚举的客户我不能不在乎作者是如何组织自己的源代码。我不希望自己的比较算法做出某种意义,虽然。太阳已经不必要地把源代码编写者处于困境。

枚举值是根据它们被声明的顺序精确有序逻辑。这是Java语言规范的一部分。因此,由此可见,如果它们是相同的枚举的成员枚举值只能进行比较。该规范要进一步保证通过的compareTo()返回的可比性顺序是一样的,其中值声明的顺序。这是一个枚举的非常定义

一种可能的解释是,compareTo应与equals一致。

equals用于枚举应当与身份平等(==)是一致的。

如果compareTo其中为非最终将有可能与行为这是不与equals一致,这将是非常反直觉覆盖它。

如果你想改变你的枚举的元素的自然顺序,改变在源代码中他们的订单。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top