J'ai une énumération comme celle-ci:
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 d'une entrée externe et je veux l'entrée correspondante - lancer une exception si une valeur n'existe pas est ok, mais de préférence je l'aurais DLT_UNKNOWN
dans ce cas.
int val = in.readInt();
PcapLinkType type = ???; /*convert val to a PcapLinkType */
EnumMap
utilise les énumérations comme les clés. Dans ce cas, l'OP veut les énumérations comme valeurs.values()
(si vos valeurs d'énumération sont séquentielles) ou une simpleswitch
instruction battrait cette méthode facilement. . Si vous n'avez qu'une poignée d'entrées dans votre,Enum
cela n'a pas beaucoup de sens d'ajouter la surcharge d'un HashMap simplement pour la commodité de ne pas avoir à mettre à jour l'switch
instruction. Cette méthode peut sembler plus élégante, mais c'est aussi un gaspillage.Il existe une méthode statique
values()
qui est documentée, mais pas là où vous vous attendez: http://docs.oracle.com/javase/tutorial/java/javaOO/enum.htmlenum MyEnum { FIRST, SECOND, THIRD; private static MyEnum[] allValues = values(); public static MyEnum fromOrdinal(int n) {return allValues[n];} }
En principe, vous pouvez utiliser juste
values()[i]
, mais il y a des rumeurs quivalues()
créeront une copie du tableau à chaque fois qu'il est appelé.la source
Vous devrez créer une nouvelle méthode statique où vous itérez PcapLinkType.values () et comparez:
public static PcapLinkType forCode(int code) { for (PcapLinkType typе : PcapLinkType.values()) { if (type.getValue() == code) { return type; } } return null; }
Ce serait bien s'il est appelé rarement. S'il est appelé fréquemment, regardez l'
Map
optimisation suggérée par d'autres.la source
Vous pouvez faire quelque chose comme ceci pour les enregistrer automatiquement dans une collection avec laquelle convertir ensuite facilement les entiers en énumération correspondante. (BTW, les ajouter à la carte dans le constructeur enum n'est pas autorisé . C'est bien d'apprendre de nouvelles choses même après de nombreuses 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<Integer, PcapLinkType> typesByValue = new HashMap<Integer, PcapLinkType>(); 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); } }
la source
si vous avez une énumération comme celle-ci
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 */
la source
Comme le dit @MeBigFatGuy, sauf que vous pouvez faire en sorte que votre
static {...}
bloc utilise une boucle sur lavalues()
collection:static { for (PcapLinkType type : PcapLinkType.values()) { intToTypeMap.put(type.getValue(), type); } }
la source
Je sais que cette question date de quelques années, mais comme Java 8 nous a, entre-temps, amené
Optional
, j'ai pensé proposer une solution en l'utilisant (etStream
etCollectors
):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<Integer, PcapLinkType> map; static { map = Arrays.stream(values()) .collect(Collectors.toMap(e -> e.value, e -> e)); } public static Optional<PcapLinkType> fromInt(int value) { return Optional.ofNullable(map.get(value)); } }
Optional
est commenull
: il représente un cas où il n'y a pas de valeur (valide). Mais c'est une alternative plus sûre pour le typenull
ou une valeur par défaut, par exempleDLT_UNKNOWN
parce que vous pourriez oublier de vérifier les casnull
ouDLT_UNKNOWN
. Ce sont deuxPcapLinkType
valeurs valides ! En revanche, vous ne pouvez pas affecter uneOptional<PcapLinkType>
valeur à une variable de typePcapLinkType
.Optional
vous fait vérifier d'abord une valeur valide.Bien sûr, si vous souhaitez conserver
DLT_UNKNOWN
pour compatibilité descendante ou pour toute autre raison, vous pouvez toujours utiliserOptional
même dans ce cas, en utilisantorElse()
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<Integer, PcapLinkType> 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); } }
la source
Vous pouvez ajouter une méthode statique dans votre énumération qui accepte un
int
comme paramètre et renvoie unPcapLinkType
.public static PcapLinkType of(int linkType) { switch (linkType) { case -1: return DLT_UNKNOWN case 0: return DLT_NULL; //ETC.... default: return null; } }
la source
switch
instruction si vous ajoutez une nouvelle énumération. Pas idéal, à mon humble avis.Voici 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); } }
la source
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; } }
la source
.values()
méthode?).--int
, mais c'est évidemment une faute de frappe.null
à la place deDLT_UKNOWN
:)static final values[] = PcapLinkType.values()
?Il n'existe aucun moyen de gérer élégamment les types énumérés basés sur des entiers. Vous pourriez envisager d'utiliser une énumération basée sur des chaînes au lieu de votre solution. Ce n'est pas toujours le moyen préféré, mais il existe toujours.
public enum Port { /** * The default port for the push server. */ DEFAULT("443"), /** * The alternative port that can be used to bypass firewall checks * made to the default <i>HTTPS</i> port. */ ALTERNATIVE("2197"); private final String portString; Port(final String portString) { this.portString = portString; } /** * Returns the port for given {@link Port} enumeration value. * @return The port of the push server host. */ public Integer toInteger() { return Integer.parseInt(portString); } }
la source