Auparavant, mes enums LegNo étaient définis simplement comme suit:
NO_LEG, LEG_ONE, LEG_TWO
et en appelant return LegNo.values()[i];
, j'ai pu obtenir la valeur associée à chaque énumération.
Mais maintenant, j'ai décidé de vouloir que LegNo
enum NO_LEG
Soit int-1 au lieu de 0, alors j'ai décidé d'utiliser un constructeur privé pour initialiser et définir sa valeur int.
NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);
private LegNo(final int leg) { legNo = leg; }
la seule chose à présent est que, parce que je le fais de cette façon, la méthode values()
ne fonctionnera pas pour l'énumération NO_LEG
. Comment puis-je obtenir l'énum associé à l'int? Y at-il un moyen efficace de le faire autre que d’utiliser une instruction case switch ou un if-elseif-elseif
Je peux voir beaucoup de SO questions concernant l'obtention de la valeur int de l'énum, mais je suis après l'inverse.
Aujourd'hui, je mettrais en œuvre ceci comme suit
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();
}
}
Vous devrez maintenir un mappage à l'intérieur de l'énum.
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);
}
}
Le bloc statique ne sera appelé qu'une seule fois, il n'y a donc pratiquement aucun problème de performances ici.
EDIT: La méthode a été renommée valueOf
car elle est plus en ligne avec les autres Java classes.
Vous pouvez également inclure une méthode statique dans l'énumération qui parcourt tous les membres et retourne la méthode correcte.
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?");
}
}
Maintenant, si vous voulez obtenir une valeur Enum par l'entier, utilisez simplement:
int myLegIndex = 1; //expected : LEG_ONE
LegNo myLeg = LegNo.getLeg(myLegIndex);
réponse de adarshr adapté à 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);
}
}
Vous pouvez également accéder à la valeur Enum correspondant à une valeur entière donnée en appelant simplement la méthode values () de la énumération LegNo. Il retourne le champ de LegNo enums: LegNo.values[0]; //returns LEG_NO LegNo.values[1]; //returns LEG_ONE LegNo.values[2]; //returns LEG_TWO
Pas précisément ce qu'il cherchait, mais plutôt proche et très simple. (Bien que le sujet soit mort, il pourrait être utile à quelqu'un d'autre.)
Java 8 voies avec valeur par défaut:
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);
}
}
appeler:
LegNo res = LegNo.find(0, () -> LegNo.NO_LEG);
ou avec exception:
LegNo res = LegNo.find(0, () -> {
throw new RuntimeException("No found");
});
Puisque votre enum ne contient que 3 éléments, le moyen le plus rapide consiste simplement à utiliser une série de if else
, comme vous l'avez suggéré.
edit: la réponse fournie par adarshr convient mieux aux cas généraux, où il existe de nombreuses valeurs enum, mais je pense que c'est une surpopulation pour votre problème.
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