我有一个这样的枚举:
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;
}
}
现在我从外部输入获取一个int并想要匹配的输入 - 如果某个值不存在则抛出异常是正常的,但在这种情况下我最好是DLT_UNKNOWN
。
int val = in.readInt();
PcapLinkType type = ???; /*convert val to a PcapLinkType */
答案 0 :(得分:96)
您需要手动执行此操作,方法是在将整数映射到枚举的类中添加静态映射,例如
private static final Map<Integer, PcapLinkType> intToTypeMap = new HashMap<Integer, PcapLinkType>();
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;
}
答案 1 :(得分:30)
有一个静态方法values()
记录,但不是你期望的那样: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];}
}
原则上,您只能使用values()[i]
,但有传言称values()
每次调用时都会创建数组的副本。
答案 2 :(得分:14)
您必须创建一个新的静态方法,迭代PcapLinkType.values()并进行比较:
public static PcapLinkType forCode(int code) {
for (PcapLinkType typе : PcapLinkType.values()) {
if (type.getValue() == code) {
return type;
}
}
return null;
}
如果很少被调用那就没问题。如果经常调用它,请查看其他人建议的Map
优化。
答案 3 :(得分:9)
你可以做这样的事情来自动将它们全部注册到一个集合中,然后可以轻松地将整数转换为相应的枚举。 (顺便说一下,在枚举构造函数is not allowed中将它们添加到地图中。即使在使用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);
}
}
答案 4 :(得分:9)
如果你有这样的枚举
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;
}
}
然后你可以像
一样使用它PcapLinkType type = PcapLinkType.values()[1]; /*convert val to a PcapLinkType */
答案 5 :(得分:4)
正如@MeBigFatGuy所说,除了你可以让static {...}
块使用values()
集合上的循环:
static {
for (PcapLinkType type : PcapLinkType.values()) {
intToTypeMap.put(type.getValue(), type);
}
}
答案 6 :(得分:4)
我知道这个问题已经有几年了,但是正如Java 8所带来的那样,同时带给我们Optional
,我想我会提供一个使用它的解决方案(和Stream
和Collectors
):
Optional
null
与null
类似:它代表没有(有效)值的情况。但它是DLT_UNKNOWN
或类型null
等默认值的更安全的替代方法,因为您可能忘记检查DLT_UNKNOWN
或PcapLinkType
个案例。它们都是有效的Optional<PcapLinkType>
值!相反,您无法将PcapLinkType
值分配给Optional
类型的变量。 DLT_UNKNOWN
会让您先检查有效值。
当然,如果您希望保留Optional
以实现向后兼容性或其他原因,即使在这种情况下,仍然可以使用orElse()
,使用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);
}
}
将其指定为默认值值:
public void dice(){
int whichOne=(int)(Math.random()*6+1);
if(whichOne==1){jLabel12.setIcon(new ImageIcon(getClass().getResource("/spanish/dice1.png")));}
else if(whichOne==2){jLabel12.setIcon(new ImageIcon(getClass().getResource("/spanish/dice2.png")));}
else if(whichOne==3){jLabel12.setIcon(new ImageIcon(getClass().getResource("/spanish/dice3.png")));}
else if(whichOne==4){jLabel12.setIcon(new ImageIcon(getClass().getResource("/spanish/dice4.png")));}
else if(whichOne==5){jLabel12.setIcon(new ImageIcon(getClass().getResource("/spanish/dice5.png")));}
else if(whichOne==6){jLabel12.setIcon(new ImageIcon(getClass().getResource("/spanish/dice6.png")));}
}
答案 7 :(得分:3)
您可以在枚举中添加静态方法,该方法接受int
作为参数并返回PcapLinkType
。
public static PcapLinkType of(int linkType) {
switch (linkType) {
case -1: return DLT_UNKNOWN
case 0: return DLT_NULL;
//ETC....
default: return null;
}
}
答案 8 :(得分:3)
这就是我使用的:
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); }
}
答案 9 :(得分:1)
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;
}
}
答案 10 :(得分:0)
没有办法优雅地处理基于整数的枚举类型。您可能会考虑使用基于字符串的枚举而不是解决方案。一直不是首选方法,但它仍然存在。
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);
}
}
答案 11 :(得分:0)
这可能不是一个很好的解决方案,但它对我有用:
public enum Type {
WATER, FIRE, GRASS;
public static Type getType(int value){
if(value==WATER.ordinal()){
return WATER;
}else if(value==FIRE.ordinal()){
return FIRE;
}else if(value==GRASS.ordinal()){
return GRASS;
}else {
return null;
}
}
}