Получение перечисления, связанного со значением int
ранее у меня были свои перечисления LegNo, определенные просто как:
NO_LEG, LEG_ONE, LEG_TWO
и return LegNo.values()[i];, я смог получить значение, связанное с каждым перечислением.
но теперь я решил, что хочу LegNo перечисление NO_LEG быть int -1 вместо 0
поэтому я решил использовать частный конструктор для инициализации и установки его значения int
NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);
private LegNo(final int leg) { legNo = leg; }
только сейчас, потому что я делаю это таким образом values() метод не будет работать для NO_LEG перечисление. Как получаю ли я перечисление, связанное с int? Есть ли какой-либо эффективный способ сделать это, кроме использования оператора case switch или if-elseif-elseif
Я вижу много вопросов SO, связанных с получением значения int из перечисления, но я после обратного.
8 ответов:
редактировать август 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<LegNo> valueOf(int value) { return Arrays.stream(values()) .filter(legNo -> legNo.value == value) .findFirst(); } }
вам придется поддерживать отображение внутри перечисления.
public enum LegNo { NO_LEG(-1), LEG_ONE(1), LEG_TWO(2); private int legNo; private static Map<Integer, LegNo> map = new HashMap<Integer, LegNo>(); 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); } }статический блок будет вызван только один раз, поэтому здесь практически нет проблем с производительностью.
изменить: переименовал метод в
valueOfпоскольку он более встроен в другие классы 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?"); } }теперь, если вы хотите получить значение перечисления целым числом, вы просто используете:
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<Integer, LegNo> 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 () на enum LegNo. Он возвращает поле перечислений LegNo:
LegNo.values[0]; //returns LEG_NO LegNo.values[1]; //returns LEG_ONE LegNo.values[2]; //returns LEG_TWOНе совсем то, что он искал, но довольно близко, хотя и очень просто. (Хотя субъект мертв, это может быть полезно для кого-то еще.)
Java 8 способ со значением по умолчанию:
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, лучше подходит для общих случаев, где есть много значений перечисления, но я думаю, что это перебор для вашей проблемы.
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)тело.LEG_ONE; / / / который возвращает 2
это также очень быстро и легко читается, так как это делается во время компиляции.
Comments