Wcześniej moje wyliczenia LegNo były zdefiniowane po prostu jako:
NO_LEG, LEG_ONE, LEG_TWO
i dzwoniąc return LegNo.values()[i];
, mogłem uzyskać wartość związaną z każdym wyliczeniem.
Ale teraz zdecydowałem, że chcę, aby LegNo
wyliczenie NO_LEG
było wartością int -1 zamiast 0, więc zdecydowałem się użyć prywatnego konstruktora do zainicjowania i ustawienia jego wartości int
NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);
private LegNo(final int leg) { legNo = leg; }
teraz jedyną rzeczą jest to, że ponieważ robię to w ten sposób, values()
metoda nie będzie działać dla NO_LEG
wyliczenia. Jak uzyskać wyliczenie skojarzone z int? Czy istnieje jakiś skuteczny sposób na zrobienie tego, inny niż użycie instrukcji przełączania case lub if-elseif-elseif
Widzę wiele pytań SO związanych z uzyskaniem wartości int z wyliczenia, ale jestem po odwrotnej kolejności.
LegNo foo = LegNo.valueOf(2);
. Poprzedni kod zwróci plikLegNo.LEG_TWO
.null
zgodnie z oczekiwaniami przy użyciu HashMap.get : zwraca wartość, na którą mapowany jest określony klucz, lub wartość null, jeśli ta mapa nie zawiera mapowania dla klucza.valueOf()
wyliczasz 1000-składową wewnątrz innej pętli.Możesz również dołączyć metodę statyczną do wyliczenia, która iteruje przez wszystkie elementy członkowskie i zwraca poprawną.
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?"); } }
Teraz, jeśli chcesz uzyskać wartość Enum jako liczbę całkowitą, po prostu użyj:
int myLegIndex = 1; //expected : LEG_ONE LegNo myLeg = LegNo.getLeg(myLegIndex);
źródło
odpowiedź adarshr dostosowana do 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); } }
źródło
Możesz również uzyskać dostęp do wartości Enum odpowiadającej podanej wartości całkowitej, po prostu wywołując metodę values () na wyliczeniu LegNo. Zwraca pole wyliczeń LegNo:
LegNo.values()[0]; //returns LEG_NO LegNo.values()[1]; //returns LEG_ONE LegNo.values()[2]; //returns LEG_TWO
Nie dokładnie to, czego szukał, ale całkiem blisko i naprawdę bardzo proste. (Chociaż temat nie żyje, może się przydać komuś innemu).
źródło
Java 8 sposób z wartością domyślną:
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); } }
zadzwonić:
LegNo res = LegNo.find(0, () -> LegNo.NO_LEG);
lub z wyjątkiem:
LegNo res = LegNo.find(0, () -> { throw new RuntimeException("No found"); });
źródło
public enum LegNo { NO_LEG(-1), LEG_ONE(1), LEG_TWO(2); private final int code; LegNo(int code) { this.code = code; ReverseStorage.reverseMap.put(code, this); } public static Optional<LegNo> getByCode(int code) { return Optional.ofNullable(ReverseStorage.reverseMap.get(code)); } private static final class ReverseStorage { private static final Map<Integer, LegNo> reverseMap = new LinkedHashMap<>(); } }
źródło
Ponieważ wyliczenie zawiera tylko 3 elementy, najszybszym sposobem będzie użycie serii
if else
, tak jak zasugerowałeś.edycja: odpowiedź, którą podał adarshr, lepiej nadaje się do ogólnych przypadków, w których istnieje wiele wartości wyliczeniowych, ale myślę, że jest to przesada dla twojego problemu.
źródło
Map
w kodzie z pewnością nie jest przesadą. Poza tym sprawia, że metoda jest dużo czystsza niż spaghetti warunków if-else.public LegNo valueOf(int value)
nie powinna być zmieniana. Jeśli-else można następnie zapisać w samym wyliczeniu. Jeśli if-else wyjdzie z wyliczenia, z pewnością stanie się niezbyt czystym kodem.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
źródło