정수 값을 일치하는 Java Enum으로 변환
다음과 같은 열거 형이 있습니다.
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 */
Integer를 열거 형에 매핑하는 클래스에 정적 맵을 추가하여 수동으로 수행해야합니다.
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;
}
이 정적 방법이다 되고 문서화,하지만 당신이 그것을 기대하지 여기서 http://docs.oracle.com/javase/tutorial/java/javaOO/enum.htmlvalues()
enum MyEnum {
FIRST, SECOND, THIRD;
private static MyEnum[] allValues = values();
public static MyEnum fromOrdinal(int n) {return allValues[n];}
}
원칙적으로를 사용할 수 values()[i]
있지만 values()
호출 될 때마다 배열의 복사본을 만드는 소문 이 있습니다.
PcapLinkType.values ()를 반복하고 비교하는 새로운 정적 메서드를 만들어야합니다.
public static PcapLinkType forCode(int code) {
for (PcapLinkType typе : PcapLinkType.values()) {
if (type.getValue() == code) {
return type;
}
}
return null;
}
드물게 호출하면 괜찮을 것입니다. 자주 호출되는 경우 Map
다른 사람들이 제안한 최적화 를 살펴보십시오 .
이와 같은 작업을 수행하여 모든 항목을 컬렉션에 자동으로 등록한 다음 정수를 해당 열거 형으로 쉽게 변환 할 수 있습니다. (BTW, enum 생성자에서 맵에 추가하는 것은 허용되지 않습니다 . 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);
}
}
이와 같은 열거 형이 있다면
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 */
@MeBigFatGuy가 말했듯이 static {...}
블록이 values()
컬렉션에 대해 루프를 사용 하도록 할 수 있다는 점을 제외하고는 다음과 같습니다.
static {
for (PcapLinkType type : PcapLinkType.values()) {
intToTypeMap.put(type.getValue(), type);
}
}
나는이 질문은 몇 살 알고 있지만, 자바 8 바와 같이, 그 사이에, 우리를 데리고 Optional
, 나는 (그것을 사용하여 솔루션을 제공 할 거라고 생각 Stream
과 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<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
is like null
: it represents a case when there is no (valid) value. But it is a more type-safe alternative to null
or a default value such as DLT_UNKNOWN
because you could forget to check for the null
or DLT_UNKNOWN
cases. They are both valid PcapLinkType
values! In contrast, you cannot assign an Optional<PcapLinkType>
value to a variable of type PcapLinkType
. Optional
makes you check for a valid value first.
Of course, if you want to retain DLT_UNKNOWN
for backward compatibility or whatever other reason, you can still use Optional
even in that case, using orElse()
to specify it as the default value:
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);
}
}
You could add a static method in your enum that accepts an int
as a parameter and returns a PcapLinkType
.
public static PcapLinkType of(int linkType) {
switch (linkType) {
case -1: return DLT_UNKNOWN
case 0: return DLT_NULL;
//ETC....
default: return null;
}
}
This is what I use:
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;
}
}
There is no way to elegantly handle integer-based enumerated types. You might think of using a string-based enumeration instead of your solution. Not a preferred way all the times, but it still exists.
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);
}
}
참고URL : https://stackoverflow.com/questions/5292790/convert-integer-value-to-matching-java-enum
'Program Tip' 카테고리의 다른 글
내 info.plist 및 .pch 파일이 어디에 있는지 Xcode에 알리는 방법 (0) | 2020.10.09 |
---|---|
사용자 지정 알림 레이아웃 및 텍스트 색상 (0) | 2020.10.09 |
자바 스크립트를 사용하여 텍스트를 강조 표시하는 방법 (0) | 2020.10.09 |
Python : 간단한 설정 / 구성 파일을 어떻게 저장 하시겠습니까? (0) | 2020.10.09 |
Jenkins / Hudson 빌드 기록을 지우려면 어떻게하나요? (0) | 2020.10.08 |