web-dev-qa-db-fra.com

Obtenir une énumération associée à la valeur int

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.

81
L-Samuels

EDIT août 2018

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.

133
adarshr

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);
20
Mike Adler

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);
    }
}
16
Marcin

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.)

8
Tadeas

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");
});
6
Dmitry Sokolyuk

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.

1
DieterDP
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
0
Tom B