Цикл для перечислений в Java - PullRequest
       3

Цикл для перечислений в Java

0 голосов
/ 25 августа 2011

У меня есть некоторые перечисления, подобные этому:

public enum Classification {
    UNKNOWN("Unknown"),
    DELETION("Deletion"),
    DUPLICATION("Duplication"), ....

, но некоторые из них имеют около 20 членов, поэтому в настоящее время в коде я имею дело с огромными блоками if / else, такими как:

int classification= rs.getInt("classification");
        if (classification == Classification.UNKNOWN.ordinal()) {
            variant.setClassification(Classification.UNKNOWN);
        } else if (classification == Classification.DELETION.ordinal()) {
            variant.setClassification(Classification.DELETION);

(rs от JDBC tho).

Есть ли у Java лучший способ для этих больших блоков if / else делать то, что я делаю?какая-то сортировка циклов?

Ответы [ 8 ]

10 голосов
/ 25 августа 2011

Вы можете использовать Enum#values(), чтобы получить все значения перечисления в массиве.Порядковый номер отображает 1: 1 в индекс массива.Добавьте следующий метод для вашего Classification enum:

public static Classification of(int ordinal) {
    if (0 <= ordinal && ordinal < values().length) {
        return values()[ordinal];
    }
    throw new IllegalArgumentException("Invalid ordinal " + ordinal);
}

и используйте его следующим образом

Classification classification = Classification.of(rs.getInt("classification"));
// ...

Однако использование порядкового номера enum для этого не является наилучшей практикой.Что, если какой-то разработчик реорганизует значения перечисления или добавляет / удаляет значения?Даже javadoc предупреждает, что он, как правило, бесполезен для разработчиков.Вместо этого присвойте каждому значению перечисления фиксированный идентификатор.Вы можете передать его как дополнительный аргумент аргумента конструктора enum.Вы даже можете использовать для этого представление String в enum.

UNKNOWN(1, "Unknown"),
DELETION(2, "Deletion"),
DUPLICATION(3, "Duplication"),
// ...

Затем вместо этого использовать это значение для DB и изменить метод of() для обхода их в цикле foreach:

public static Classification of(int id) {
    for (Classification classification : values()) {
        if (classification.id == id) {
            return classification;
        }
    }
    throw new IllegalArgumentException("Invalid id " + id);
}
3 голосов
/ 25 августа 2011

Если значение db является порядковым номером Enum, то:

int classification= rs.getInt("classification");
variant.setClassification(Classification.values()[classification]);

Я оставлю проверку границ в качестве упражнения для читателя.

1 голос
/ 25 августа 2011

Если вы хотите и можете хранить строковое представление (это хорошая техника) ENUM в вашей базе данных, см. Ссылка от Гарета Дэвиса в комментариях выше . Если вы не хотите и / или не можете сохранить строковое представление и должны продолжить с порядковым представлением, я предлагаю использовать Map. Вот пример кода:

public class EnumMap
{
    private enum FistSounds
    {
        Blam, Kapow, Zowie, Biff;

        private static Map<Integer, FistSounds> ordinalMap = new HashMap<Integer, FistSounds>();

        static
        {
            ordinalMap.put(Blam.ordinal(), Blam);
            ordinalMap.put(Kapow.ordinal(), Kapow);
            ordinalMap.put(Zowie.ordinal(), Zowie);
            ordinalMap.put(Biff.ordinal(), Biff);
        }

        public static final FistSounds getByOrdinal(final int enumIndex)
        {
            return ordinalMap.get(enumIndex);
        }
    }

    public static void main(String[] args)
    {
        FistSounds fistSound;

        for (int index = -1; index < 5; ++index)
        {
            fistSound = FistSounds.getByOrdinal(index);

            System.out.print("Ordinal: ");
            System.out.print(index);
            System.out.print(", FistSound: ");
            System.out.println(fistSound);
        }
    }
}
1 голос
/ 25 августа 2011

Вместо хранения ordinal вы можете сохранить name и использовать метод valueOf для преобразования String обратно в тип Enum.

1 голос
/ 25 августа 2011

Используйте variant.setClassification(YourEnumClassHere.values()[classification]). Enum.values() возвращает массив всех объявленных перечислений в этом классе.

1 голос
/ 25 августа 2011

Вы можете перебирать значения перечисления через объект, который возвращает метод someEnum.values():

for (Classification clz : Classification.values()) doSomethingWith(clz);

найдено здесь

Я не знаю, чем конкретно могу вам помочь, поскольку не знаю, что делает rs.getInt(String).

Кажется, он возвращает целое число, представляющее значение перечисления Classification, но почему?

0 голосов
/ 25 августа 2011

Перечисления также могут использоваться в выражениях switch см. Здесь

0 голосов
/ 25 августа 2011

Я бы порекомендовал использовать оператор switch, если логика выполнения отличается для каждого случая ....

делайте так, как инструктирует @Gareth Davis, а затем просто используйте оператор switch и обрабатывайте каждый случай, как требуется.

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