61

Is there a way to check if an enum value is 'greater/equal' to another value?

I want to check if an error level is 'error or above'.

asked Jul 19, 2009 at 11:09

6 Answers 6

68

All Java enums implements Comparable: http://java.sun.com/javase/6/docs/api/java/lang/Enum.html

You can also use the ordinal method to turn them into ints, then comparison is trivial.

if (ErrorLevel.ERROR.compareTo(someOtherLevel) <= 0) {
 ...
}
answered Jul 19, 2009 at 11:13
Sign up to request clarification or add additional context in comments.

3 Comments

It's not really an enum, apparently. But it has a method 'isGreaterOrEqual()'
@ripper234: Your question says "enum"
The take-home message from docs.oracle.com/javase/7/docs/api/java/lang/… is: "The natural order implemented by this method is the order in which the constants are declared". Thus enum { TRACE, DEBUG, INFO, WARN } means: TRACE < DEBUG < INFO < WARN.
34

A version which is much more expressive would be

myError.isErrorOrAbove(otherError)

or

myError.isWorseThan(otherError)

This way you can define the ordering inside the Enum and can change the implementation internally if you like. Now the clients of the Enum can compare values without knowing any details about it.

A possible implementation whould be

public enum ErrorLevel {
 INFO(0),
 WARN(1),
 ERROR(2),
 FATAL(3);
 private Integer severity;
 ErrorLevel(int severity) {
 this.severity = severity;
 }
 public boolean isWorseThan(ErrorLevel other) {
 return this.severity > other.severity;
 }
}

I also would not recommend using the ordinal() method for comparison, because when somebody changes the order the Enum values are defined you could get unexpected behaviour.

answered Dec 14, 2012 at 10:25

1 Comment

Agreed. Relying on ordinal positions is a huge mistake and could potentially lead to some very difficult to trace bugs.
14

Java enum has already build in compareTo(..) method, which uses the enum position (aka ordinal) to compare one object to other. The position is determined based on the order in which the enum constants are declared , where the first constant is assigned an ordinal of zero.
If that arrangement is unsuitable, you may need to define you own comparator by adding internal field(s) as shown below:

import java.util.Comparator;
public enum Day {
 MONDAY(1, 3),
 TUESDAY(2, 6),
 WEDNESDAY(3, 5),
 THURSDAY(4, 4),
 FRIDAY(5, 2),
 SATURDAY(6, 1),
 SUNDAY(0, 0);
 private final int calendarPosition;
 private final int workLevel;
 Day(int position, int level) {
 calendarPosition = position;
 workLevel = level;
 }
 int getCalendarPosition(){ return calendarPosition; } 
 int getWorkLevel() { return workLevel; }
 public static Comparator<Day> calendarPositionComparator = new Comparator<Day>() {
 public int compare(Day d1, Day d2) {
 return d1.getCalendarPosition() - d2.getCalendarPosition();
 }
 };
 public static Comparator<Day> workLevelComparator = new Comparator<Day>() {
 public int compare(Day d1, Day d2) {
 // descending order, harder first
 return d2.getWorkLevel() - d1.getWorkLevel();
 }
 }; 
}

Driver to check if all works:

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class EnumTest
{
 public static void main (String[] args) {
 List<Day> allDays = Arrays.asList(Day.values());
 System.out.println("===\nListing days in order of calendar position:");
 Collections.sort(allDays, Day.calendarPositionComparator);
 showItems(allDays);
 System.out.println("===\nListing days in order of work level:");
 Collections.sort(allDays, Day.workLevelComparator);
 showItems(allDays);
 }
 public static void showItems(List<Day> days) {
 for (Day day : days) {
 System.out.println(day.name());
 }
 }
}
answered Jan 14, 2015 at 23:23

3 Comments

Thats horrible by the default implementation to mark it as final. I mean if someone rearranges the enum order because it looks prettier, then you entire behaviour might change.
@mjs that is why I recommend not to use Enum ordinal, but a value as a constructor argument.
yes I opt for that too.
8

Assuming you've defined them in order of severity, you can compare the ordinals of each value. The ordinal is its position in its enum declaration, where the initial constant is assigned an ordinal of zero.

You get the ordinal by calling the ordinal() method of the value.

answered Jul 19, 2009 at 11:13

1 Comment

Thats horrible by the default implementation to mark it as final. I mean if someone rearranges the enum order because it looks prettier, then you entire behaviour might change
5

I want to check if an error level is 'error or above'.

Such an enum should have a level associated with it. So to find equals or greater you should compare the levels.

Using ordinal relies on the order the enum values appear. If you rely on this you should document it otherwise such a dependency can lead to brittle code.

answered Jul 19, 2009 at 11:18

Comments

1

Another option would be

enum Blah {
 A(false), B(false), C(true);
 private final boolean isError;
 Blah(boolean isErr) {isError = isErr;}
 public boolean isError() { return isError; }
}

From your question, I'm assuming you're using enum to designate some kind of return value, some of which are error states. This implementation has the advantage of not having to add the new return types in a particular place (and then adjust your test value), but has the disadvantage of needing some extra work in initializing the enum.

Pursuing my assumption a bit further, are error codes something for the user? A debugging tool? If it's the latter, I've found the exception handling system to be pretty alright for Java.

answered Sep 8, 2009 at 0:29

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.