【发布时间】:2009-07-19 11:09:57
【问题描述】:
有没有办法检查一个枚举值是否“大于/等于”另一个值?
我想检查错误级别是否为“错误或以上”。
【问题讨论】:
有没有办法检查一个枚举值是否“大于/等于”另一个值?
我想检查错误级别是否为“错误或以上”。
【问题讨论】:
所有 Java 枚举都实现 Comparable:http://java.sun.com/javase/6/docs/api/java/lang/Enum.html
你也可以用ordinal的方法把它们变成ints,那么比较就很简单了。
if (ErrorLevel.ERROR.compareTo(someOtherLevel) <= 0) {
...
}
【讨论】:
一个更具表现力的版本是
myError.isErrorOrAbove(otherError)
或
myError.isWorseThan(otherError)
通过这种方式,您可以在 Enum 内部定义排序,并且可以根据需要在内部更改实现。现在 Enum 的客户端可以在不知道任何细节的情况下比较值。
一个可能的实现应该是
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;
}
}
我也不建议使用 ordinal() 方法进行比较,因为当有人更改 Enum 值定义的顺序时,您可能会得到意外的行为。
【讨论】:
Java enum 已经内置了compareTo(..) 方法,它使用枚举位置(又名序数)来比较一个对象和另一个对象。位置是根据声明 enum 常量的顺序确定的
,其中第一个常数的序数为零。
如果这种安排不合适,您可能需要通过添加内部字段来定义自己的比较器,如下所示:
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();
}
};
}
驱动检查是否一切正常:
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());
}
}
}
【讨论】:
假设您已按严重性顺序定义它们,您可以比较每个值的序数。序数是它在枚举声明中的位置,其中初始常量的序数为零。
通过调用值的 ordinal() 方法获取序数。
【讨论】:
我想检查错误级别是否为“错误或以上”。
这样的枚举应该有一个与之关联的级别。因此,要找到等于或更大的值,您应该比较级别。
使用序数依赖于枚举值出现的顺序。如果你依赖它,你应该记录它,否则这种依赖会导致脆弱的代码。
【讨论】:
另一种选择是
enum Blah {
A(false), B(false), C(true);
private final boolean isError;
Blah(boolean isErr) {isError = isErr;}
public boolean isError() { return isError; }
}
根据您的问题,我假设您使用枚举来指定某种返回值,其中一些是错误状态。此实现的优点是不必在特定位置添加新的返回类型(然后调整您的测试值),但缺点是在初始化枚举时需要一些额外的工作。
进一步追寻我的假设,错误代码对用户有用吗?调试工具?如果是后者,我发现异常处理系统对于 Java 来说还不错。
【讨论】: