How can't we compare two enum values with '<'?
Asked Answered
D

3

28

If enum implements Comparable so why can't compare with < or >?

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 };
Downstream answered 25/10, 2012 at 13:56 Comment(2)
What does this question have to do with the SCJP/OCPJP?Rage
It is in exam topics Section 1: Declarations, Initialization and Scoping * Develop code that declares classes (including abstract and all forms of nested classes), interfaces, and enums, and includes the appropriate use of package and import statements (including static imports). * Develop code that declares, initializes, and uses primitives, arrays, enums, and objects as static, instance, and local variables. Also, use legal identifiers for variable names. education.oracle.com/pls/web_prod-plq-dad/…Downstream
V
47

You can do this:

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

Of course, assuming that BIGGEST was declared after BIG in the enumeration. The ordinal value in an enumeration is implicitly tied to the declaration order, by default the first value is assigned value 0, the second value 1 and so on.

So if yo declared the enumeration like this, things will work:

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
}
Volt answered 25/10, 2012 at 13:59 Comment(5)
Is it correct to say that PinSize.BIGGEST is a reference variable like e.g. int[] array; ?Tonyatonye
@miller.bartek PinSize.BIGGEST is an enum value, it's not correct to compare it with an array. And anyway, in Java all variables pointing to objects (including enums, arrays) are referencesFourpence
So is it correct to say that it's not possible to use '<' nor '>' operators because PinSize.BIGGEST is a reference (represents address in memory) and there's no point in comparing memory address's and it's the same for all the other references (Object, String, int[], etc.)?Tonyatonye
@miller.bartek right, you can't compare references using <, >. Those operators only work for basic types, like int, float, etc. For comparing references, use the method compareTo() implementing Comparator if necessary.Fourpence
I think I prefer using b1.compareTo(b2), rather than comparing results of ordinal(), given the Enum.ordinal javadoc: "Most programmers will have no use for this method. It is designed for use by sophisticated enum-based data structures, such as EnumSet and EnumMap." More thought on this, (though not the < / > case specifically) in Josh Bloch 2nd ed item 31.Anethole
R
19

Implementing Comparable doesn't mean that you can use < or >. You can only use those with numeric values.

Implementing Comparable means that there's a compareTo() method. Try this:

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

The compareTo() method will return an int that is smaller than, equal to, or bigger than 0, depending on which value is "bigger". In the case of enum values, the "size" depends on the order of the enum value definitions.

Rage answered 25/10, 2012 at 13:58 Comment(0)
T
2

The answers provided explain the problem well, but I would like to add my insights, because I feel that they don't answer question "why can't compare with < or >"?. The problem comes down to comparing references. PinSize.BIGGEST and PinSize.BIGGERER are reference variables. The same as the below:

String s;
int[] array;
MyObject myObject;

They represent addresses in memory. What is more, enums are singletons so there is always one object of the specified kind. Because of that the below line is allowed and returns true.

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

Trying to check if one address in memory is greater or smaller than the other address in memory is impossible. Implementing Comparable interface and compareTo() method gives a chance to provide your own custom way of comparing objects not addresses in memory.

System.out.println(PinSize.BIG > PinSize.BIGGERER); // not possible
Tonyatonye answered 25/10, 2012 at 14:29 Comment(1)
Pointer comparison indeed does not make any sense, but the question boils down to why Java does not define a < b to be equivalen to a.compareTo(b) < 0. (I don't know any compelling reason that could be applied to Java, other than "there were unexpected interactions with other language elements".)Turanian

© 2022 - 2024 — McMap. All rights reserved.