【问题标题】:How can't we compare two enum values with '<'?我们怎么不能用'<'比较两个枚举值?
【发布时间】:2012-10-25 13:56:53
【问题描述】:

如果枚举实现了 Comparable 那为什么不能与 比较?

public class Dream    
{
    public static void main(String... args)
    {
        System.out.println(PinSize.BIG == PinSize.BIGGER); //false
        System.out.println(PinSize.BIG == PinSize.BIG); //true
        System.out.println(PinSize.BIG.equals(PinSize.BIGGER));//false
        System.out.println(PinSize.BIG > PinSize.BIGGERER);// compilation error
        //can't be compared
        System.out.println(PinSize.BIG.toString().equals(PinSize.BIGGER));// #4
        PinSize b = PinSize.BIG ;
        System.out.println( b instanceof Comparable);// true
    }  
}
enum PinSize { BIG, BIGGER, BIGGERER };

【问题讨论】:

  • 这个问题与 SCJP/OCPJP 有什么关系?
  • 在考试主题中 第 1 节:声明、初始化和范围 * 开发声明类(包括抽象类和所有形式的嵌套类)、接口和枚举的代码,并包括适当使用包和导入语句(包括静态导入)。 * 开发声明、初始化和使用原语、数组、枚举和对象作为静态、实例和局部变量的代码。此外,对变量名使用合法标识符。 education.oracle.com/pls/web_prod-plq-dad/…

标签: java enums scjp ocpjp


【解决方案1】:

你可以这样做:

PinSize.BIGGEST.ordinal() > PinSize.BIG.ordinal()  // evaluates to `true`

当然,假设BIGGEST 在枚举中声明之后 BIG。枚举中的序数值与声明顺序隐式绑定,默认情况下,第一个值分配值0,第二个值分配值1,依此类推。

所以如果你像这样声明枚举,一切都会奏效:

public enum PinSize {
    SMALLEST,  // ordinal value: 0
    SMALL,     // ordinal value: 1
    NORMAL,    // ordinal value: 2
    BIG,       // ordinal value: 3
    BIGGER,    // ordinal value: 4
    BIGGEST;   // ordinal value: 5
}

【讨论】:

  • 说 PinSize.BIGGEST 是一个参考变量是否正确,例如int[] 数组; ?
  • @miller.bartek PinSize.BIGGEST 是一个枚举值,将其与数组进行比较是不正确的。无论如何,在 Java 中,所有指向对象(包括枚举、数组)的变量都是引用
  • 所以说不能使用“”运算符是否正确,因为 PinSize.BIGGEST 是一个引用(表示内存中的地址),比较内存地址和所有其他引用(对象、字符串、int[] 等)都相同吗?
  • @miller.bartek 对,您无法使用 &lt;&gt; 比较参考。这些运算符仅适用于基本类型,如intfloat 等。如果需要比较引用,请使用实现Comparator 的方法compareTo()
  • 我认为我更喜欢使用b1.compareTo(b2),而不是比较ordinal() 的结果,因为 Enum.ordinal javadoc:“大多数程序员不会使用这种方法。它是为复杂的基于枚举的数据结构,例如 EnumSet 和 EnumMap。”在 Josh Bloch 第 2 版第 31 条中对此进行了更多思考(尽管不是具体的 > 案例。
【解决方案2】:

实现Comparable 意味着您可以使用&lt;&gt;。您可以使用带有数值的那些。

实现Comparable 意味着有一个compareTo() 方法。试试这个:

System.out.println(PinSize.BIG.compareTo(PinSize.BIGGER));

compareTo() 方法将返回小于、等于或大于 0 的 int,具体取决于哪个值“更大”。对于enum 值,“大小”取决于枚举值定义的顺序。

【讨论】:

    【解决方案3】:

    提供的答案很好地解释了这个问题,但我想补充一下我的见解,因为我觉得他们没有回答“为什么不能与 比较”的问题?问题归结为比较参考。 PinSize.BIGGEST 和 PinSize.BIGGERER 是参考变量。下同:

    String s;
    int[] array;
    MyObject myObject;
    

    它们代表内存中的地址。更重要的是,枚举是单例的,所以总是有一个指定类型的对象。因此,允许以下行并返回 true。

    System.out.println(PinSize.BIG == PinSize.BIG); //true
    

    试图检查内存中的一个地址是大于还是小于内存中的另一个地址是不可能的。实现 Comparable 接口和 compareTo() 方法可以提供您自己的自定义方法来比较对象而不是内存中的地址。

    System.out.println(PinSize.BIG > PinSize.BIGGERER); // not possible
    

    【讨论】:

    • 指针比较确实没有任何意义,但问题归结为为什么Java没有将a &lt; b定义为等同于a.compareTo(b) &lt; 0。 (我不知道有任何令人信服的理由可以应用于 Java,除了“与其他语言元素发生了意外的交互”。)
    猜你喜欢
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多