Convertir la valeur entière en Java Enum correspondant

J’ai un enum comme ça:

public enum PcapLinkType { DLT_NULL(0) DLT_EN10MB(1) DLT_EN3MB(2), DLT_AX25(3), /*snip, 200 more enums, not always consecutive.*/ DLT_UNKNOWN(-1); private final int value; PcapLinkType(int value) { this.value= value; } } 

Maintenant, j’obtiens un int depuis l’entrée externe et je veux l’entrée correspondante – lancer une exception si une valeur n’existe pas est acceptable, mais je préférerais que ce soit DLT_UNKNOWN dans ce cas.

 int val = in.readInt(); PcapLinkType type = ???; /*convert val to a PcapLinkType */ 

Vous devrez le faire manuellement en ajoutant une carte statique dans la classe qui mappe les entiers aux énumérations, telles que

 private static final Map intToTypeMap = new HashMap(); static { for (PcapLinkType type : PcapLinkType.values()) { intToTypeMap.put(type.value, type); } } public static PcapLinkType fromInt(int i) { PcapLinkType type = intToTypeMap.get(Integer.valueOf(i)); if (type == null) return PcapLinkType.DLT_UNKNOWN; return type; } 

Il y a une méthode statique values() qui est documentée, mais pas où vous vous y attendriez: http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

 enum MyEnum { FIRST, SECOND, THIRD; private static MyEnum[] allValues = values(); public static MyEnum fromOrdinal(int n) {return allValues[n];} } 

En principe, vous ne pouvez utiliser que des values()[i] , mais il y a des rumeurs selon lesquelles des values() créeront une copie du tableau à chaque appel.

Vous devrez créer une nouvelle méthode statique pour itérer PcapLinkType.values ​​() et comparer:

 public static PcapLinkType forCode(int code) { for (PcapLinkType typе : PcapLinkType.values()) { if (type.getValue() == code) { return type; } } return null; } 

Ce serait bien si on l’appelle rarement. Si elle est appelée fréquemment, consultez l’optimisation de Map proposée par d’autres utilisateurs.

si tu as enum comme ça

 public enum PcapLinkType { DLT_NULL(0) DLT_EN10MB(1) DLT_EN3MB(2), DLT_AX25(3), DLT_UNKNOWN(-1); private final int value; PcapLinkType(int value) { this.value= value; } } 

alors vous pouvez l’utiliser comme

 PcapLinkType type = PcapLinkType.values()[1]; /*convert val to a PcapLinkType */ 

Vous pouvez faire quelque chose comme ça pour les enregistrer automatiquement dans une collection avec laquelle convertir facilement les entiers en enum correspondant. (BTW, les append à la carte dans le constructeur enum n’est pas autorisé . C’est bien d’apprendre de nouvelles choses même après plusieurs années d’utilisation de Java. 🙂

 public enum PcapLinkType { DLT_NULL(0), DLT_EN10MB(1), DLT_EN3MB(2), DLT_AX25(3), /*snip, 200 more enums, not always consecutive.*/ DLT_UNKNOWN(-1); private static final Map typesByValue = new HashMap(); static { for (PcapLinkType type : PcapLinkType.values()) { typesByValue.put(type.value, type); } } private final int value; private PcapLinkType(int value) { this.value = value; } public static PcapLinkType forValue(int value) { return typesByValue.get(value); } } 

Comme @MeBigFatGuy le dit, sauf que vous pouvez faire en sorte que votre bloc static {...} utilise une boucle sur la collection values() :

 static { for (PcapLinkType type : PcapLinkType.values()) { intToTypeMap.put(type.getValue(), type); } } 

Je sais que cette question a quelques années, mais comme Java 8 nous a apporté, en attendant, une Optional , j’ai pensé proposer une solution (et Stream et Collectors ):

 public enum PcapLinkType { DLT_NULL(0), DLT_EN3MB(2), DLT_AX25(3), /*snip, 200 more enums, not always consecutive.*/ // DLT_UNKNOWN(-1); // <--- NO LONGER NEEDED private final int value; private PcapLinkType(int value) { this.value = value; } private static final Map map; static { map = Arrays.stream(values()) .collect(Collectors.toMap(e -> e.value, e -> e)); } public static Optional fromInt(int value) { return Optional.ofNullable(map.get(value)); } } 

Optional est comme null : il représente un cas où il n’y a pas de valeur (valide). Mais c’est une alternative plus sûre à null ou une valeur par défaut telle que DLT_UNKNOWN car vous pourriez oublier de vérifier les cas null ou DLT_UNKNOWN . Ce sont deux valeurs PcapLinkType valides! En revanche, vous ne pouvez pas affecter une valeur Optional à une variable de type PcapLinkType . Optional vous vérifiez d’abord une valeur valide.

Bien sûr, si vous souhaitez conserver DLT_UNKNOWN pour la compatibilité descendante ou pour toute autre raison, vous pouvez toujours utiliser la fonctionnalité Optional dans ce cas, en utilisant orElse() pour le spécifier comme valeur par défaut:

 public enum PcapLinkType { DLT_NULL(0), DLT_EN3MB(2), DLT_AX25(3), /*snip, 200 more enums, not always consecutive.*/ DLT_UNKNOWN(-1); private final int value; private PcapLinkType(int value) { this.value = value; } private static final Map map; static { map = Arrays.stream(values()) .collect(Collectors.toMap(e -> e.value, e -> e)); } public static PcapLinkType fromInt(int value) { return Optional.ofNullable(map.get(value)).orElse(DLT_UNKNOWN); } } 

Vous pouvez append une méthode statique dans votre enum qui accepte un int comme paramètre et renvoie un PcapLinkType .

 public static PcapLinkType of(int linkType) { switch (linkType) { case -1: return DLT_UNKNOWN case 0: return DLT_NULL; //ETC.... default: return null; } } 

C’est ce que j’utilise:

 public enum Quality {ENOUGH,BETTER,BEST; private static final int amount = EnumSet.allOf(Quality.class).size(); private static Quality[] val = new Quality[amount]; static{ for(Quality q:EnumSet.allOf(Quality.class)){ val[q.ordinal()]=q; } } public static Quality fromInt(int i) { return val[i]; } public Quality next() { return fromInt((ordinal()+1)%amount); } } 
 static final PcapLinkType[] values = { DLT_NULL, DLT_EN10MB, DLT_EN3MB, null ...} ... public static PcapLinkType getPcapLinkTypeForInt(int num){ try{ return values[int]; }catch(ArrayIndexOutOfBoundsException e){ return DLT_UKNOWN; } }