简体   繁体   English

比较Java枚举值

[英]Compare Java enum values

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'. 我想检查错误级别是“错误还是以上”。

All Java enums implements Comparable: http://java.sun.com/javase/6/docs/api/java/lang/Enum.html 所有Java枚举都实现了Comparable: http//java.sun.com/javase/6/docs/api/java/lang/Enum.html

You can also use the ordinal method to turn them into int s, then comparison is trivial. 您也可以使用ordinal方法将它们转换为int ,然后进行比较是微不足道的。

if (ErrorLevel.ERROR.compareTo(someOtherLevel) <= 0) {
  ...
}

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. 这样,您可以在Enum中定义排序,并可以根据需要在内部更改实现。 Now the clients of the Enum can compare values without knowing any details about it. 现在,Enum的客户端可以在不知道任何细节的情况下比较值。

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. 我也不建议使用ordinal()方法进行比较,因为当某人更改顺序时,Enum值被定义,您可能会遇到意外行为。

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. 您可以通过调用值的ordinal()方法获得序数。

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. 如果你依赖于此,你应该记录它,否则这样的依赖会导致代码脆弱。

Java enum has already build in compareTo(..) method, which uses the enum position (aka ordinal) to compare one object to other. Java 枚举已经构建了compareTo(..)方法,该方法使用枚举位置(也称为序数)将一个对象与另一个对象进行比较。 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());
    }
  }
}

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. 如果是后者,我发现Java的异常处理系统非常好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM