Получение перечисления, связанного со значением int
Раньше у меня были перечисления LegNo, заданные просто как:
NO_LEG, LEG_ONE, LEG_TWO
и вызывая return LegNo.values()[i];
, мне удалось получить значение, связанное с каждым перечислением.
Но теперь я решил, что я хочу, чтобы LegNo
enum 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 case или if-elseif-elseif
Я вижу много вопросов SO, связанных с получением значения int из перечисления, но это я после обратного.
Ответы
Ответ 1
Вам нужно будет поддерживать отображение внутри перечисления.
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);
}
}
Статический блок будет вызываться только один раз, поэтому проблема с производительностью здесь практически отсутствует.
EDIT: переименован метод в valueOf
, поскольку он больше связан с другими классами Java.
Ответ 2
Вы также можете включить статический метод в перечисление, который выполняет итерацию через все члены и возвращает правильный.
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);
Ответ 3
adarshr answer адаптирован к 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);
}
}
Ответ 4
Вы также можете получить доступ к значению Enum, соответствующему заданному целочисленному значению, просто путем вызова метода values () для перечисления LegNo. Он возвращает поле перечислений LegNo:
LegNo.values[0]; //returns LEG_NO
LegNo.values[1]; //returns LEG_ONE
LegNo.values[2]; //returns LEG_TWO
Не то, что он искал, но довольно близко, хотя и очень просто. (Хотя объект мертв, он может быть полезен для кого-то другого.)
Ответ 5
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");
});
Ответ 6
Поскольку ваше перечисление содержит только 3 элемента, самым быстрым способом будет просто использовать серию if else
, как вы и предполагали.
edit: ответ, который предоставлен adarshr, лучше подходит для общих случаев, где есть много значений перечисления, но я думаю, что это является излишним для вашей проблемы.
Ответ 7
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
Ответ 8
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
это также очень быстро и легко читается, так как оно выполняется во время компиляции.