Получение enums, связанного со значением int
Раньше у меня были перечислены Legno enums просто:
NO_LEG, LEG_ONE, LEG_TWO
и путем вызова return LegNo.values()[i];
, Я смог получить значение, связанное с каждым перечислением.
Но теперь я решил, что хочу, чтобы LegNo
enum NO_LEG
был int -1 вместо 0, поэтому я решил использовать частный конструктор для инициализации и установить его значение int
- Хэш-карта на основе диска
- Как вы выполняете предельный запрос в HQL?
- Как добавить метод в Enumeration в Scala?
- Объединение сырых типов и общих методов
- Требуется тип сетки для редактора пикселей
NO_LEG(-1), LEG_ONE(1), LEG_TWO(2); private LegNo(final int leg) { legNo = leg; }
теперь единственное, что, поскольку я делаю это так, метод values()
не будет работать для enums NO_LEG
. Как получить перечисление, связанное с int? Есть ли эффективный способ сделать это, кроме использования оператора case case или if-elseif-elseif
Я вижу много вопросов SO, связанных с получением значения int из enums, но я за ним обратный.
- Как передать параметр в Java-stream?
- Конечная локальная переменная не может быть назначена
- Получение текста после соответствия регулярному выражению
- Поведение статических блоков с наследованием
- Есть ли эквивалент java.util.regex для шаблонов типа «glob»?
- Почему autoboxing не отменяет varargs при использовании перегрузки методов в Java 7?
- Java String.equals против ==
- Java, как рисовать постоянно меняющуюся графику
EDIT Август 2018
Сегодня я бы выполнил это следующим образом
public enum LegNo { NO_LEG(-1), LEG_ONE(1), LEG_TWO(2); private final int value; LegNo(int value) { this.value = value; } public static Optional valueOf(int value) { return Arrays.stream(values()) .filter(legNo -> legNo.value == value) .findFirst(); } }
Вам нужно будет поддерживать отображение внутри enums.
public enum LegNo { NO_LEG(-1), LEG_ONE(1), LEG_TWO(2); private int legNo; private static Map map = new HashMap(); static { for (LegNo legEnum : LegNo.values()) { map.put(legEnum.legNo, legEnum); } } private LegNo(final int leg) { legNo = leg; } public static LegNo valueOf(int legNo) { return map.get(legNo); } }
Статический блок будет вызываться только один раз, поэтому здесь практически нет проблемы с производительностью.
EDIT: переименован метод в valueOf
поскольку он больше связан с другими classами Java.
Вы также можете включить статический метод в перечисление, который выполняет итерацию через всех членов и возвращает правильный.
public enum LegNo { NO_LEG(-1), LEG_ONE(1), LEG_TWO(2); private int legIndex; private LegNo(int legIndex) { this.legIndex = legIndex; } public static LegNo getLeg(int legIndex) { for (LegNo l : LegNo.values()) { if (l.legIndex == legIndex) return l; } throw new IllegalArgumentException("Leg not found. Amputated?"); } }
Теперь, если вы хотите получить значение Enum целым числом, вы просто используете:
int myLegIndex = 1; //expected : LEG_ONE LegNo myLeg = LegNo.getLeg(myLegIndex);
Ответ adarshr адаптирован к Java 8:
import static java.util.Arrays.stream; import static java.util.stream.Collectors.toMap; import java.util.Map; public enum LegNo { NO_LEG(-1), LEG_ONE(1), LEG_TWO(2); private final int legNo; private final static Map map = stream(LegNo.values()).collect(toMap(leg -> leg.legNo, leg -> leg)); private LegNo(final int leg) { legNo = leg; } public static LegNo valueOf(int legNo) { return map.get(legNo); } }
Вы также можете получить доступ к значению Enum, соответствующему заданному целочисленному значению, просто путем вызова метода values () для enums LegNo. Он возвращает поле перечислений LegNo.values[0]; //returns LEG_NO LegNo.values[1]; //returns LEG_ONE LegNo.values[2]; //returns LEG_TWO
: LegNo.values[0]; //returns LEG_NO LegNo.values[1]; //returns LEG_ONE LegNo.values[2]; //returns LEG_TWO
LegNo.values[0]; //returns LEG_NO LegNo.values[1]; //returns LEG_ONE LegNo.values[2]; //returns LEG_TWO
Не совсем то, что он искал, но довольно близко, хотя и очень просто. (Хотя объект мертв, он может быть полезен для кого-то другого).
Java 8-way со значением по умолчанию:
public enum LegNo { NO_LEG(-1), LEG_ONE(1), LEG_TWO(2); private final int legNo; LegNo(int legNo) { this.legNo = legNo; } public static LegNo find(int legNo, Supplier extends LegNo> byDef) { return Arrays.asList(LegNo.values()).stream() .filter(e -> e.legNo == legNo).findFirst().orElseGet(byDef); } }
звонить:
LegNo res = LegNo.find(0, () -> LegNo.NO_LEG);
или с Исключением:
LegNo res = LegNo.find(0, () -> { throw new RuntimeException("No found"); });
Поскольку ваше перечисление содержит только 3 элемента, самым быстрым способом будет просто использовать серию if else
, как вы предлагали.
edit: ответ, который предлагает adarshr, лучше подходит для общих случаев, где есть много значений enum, но я думаю, что это слишком много для вашей проблемы.
public enum LegNo { NO_LEG(-1), LEG_ONE(1), LEG_TWO(2); private int legNo; private LegNo(int leg) { legNo = leg; } public static LegNo valueOf(int legNo) { for (LegNo leg : LegNo.values()) { if (leg.legNo == legNo) return leg; } } } assert LegNo.valueOf(2) == LegNo.LEG_TWO assert LegNo.valueOf(3) == null
public enum body { NO_LEG = 0, // bit 1 LEG_ONE = 2, // bit 2 LEG_TWO = 4, // bit 3 NO_ARM = 8, // bit 4 ARM_ONE = 16, // bit 5 ARM_TWO = 32 // bit 6 }
используйте его так (int) body.LEG_ONE; ///, который возвращает 2
это также очень быстро и легко читается, поскольку оно выполняется во время компиляции.