Сравните значения перечисления Java - PullRequest
41 голосов
/ 19 июля 2009

Есть ли способ проверить, является ли значение перечисления «большим / равным» другому значению?

Я хочу проверить, является ли уровень ошибки «ошибка или выше».

Ответы [ 6 ]

53 голосов
/ 19 июля 2009

Все перечисления Java реализуются сравнимо: http://java.sun.com/javase/6/docs/api/java/lang/Enum.html

Вы также можете использовать метод ordinal, чтобы превратить их в int с, тогда сравнение будет тривиальным.

if (ErrorLevel.ERROR.compareTo(someOtherLevel) <= 0) {
  ...
}
25 голосов
/ 14 декабря 2012

Версия, которая намного более выразительна, будет

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, вы можете получить неожиданное поведение.

8 голосов
/ 19 июля 2009

Предполагая, что вы определили их в порядке серьезности, вы можете сравнить порядковые номера каждого значения. Порядковый номер - это его позиция в объявлении перечисления, где начальная константа имеет порядковый номер, равный нулю.

Вы получаете порядковый номер, вызывая метод ordinal () для значения.

5 голосов
/ 15 января 2015

Java enum уже имеет встроенный метод compareTo (..) , который использует позицию enum (или порядковый номер) для сравнения одного объекта с другим. Положение определяется на основе порядка, в котором объявлены константы 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());
    }
  }
}
5 голосов
/ 19 июля 2009

Я хочу проверить, является ли уровень ошибки «ошибка или выше».

Такой enum должен иметь связанный с ним уровень. Таким образом, чтобы найти равных или больше, вы должны сравнить уровни.

Использование порядкового номера зависит от порядка отображения значений перечисления. Если вы полагаетесь на это, вы должны документировать это, иначе такая зависимость может привести к хрупкому коду.

1 голос
/ 08 сентября 2009

Другой вариант будет

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

Исходя из вашего вопроса, я предполагаю, что вы используете enum для обозначения некоторого возвращаемого значения, некоторые из которых являются состояниями ошибки. Преимущество этой реализации заключается в том, что нет необходимости добавлять новые типы возвращаемых данных в определенном месте (а затем корректировать тестовое значение), но недостатком является необходимость дополнительной работы при инициализации перечисления.

Продолжая мое предположение, являются ли коды ошибок для пользователя? Инструмент отладки? Если это последнее, я обнаружил, что система обработки исключений вполне подходит для Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...