문자열 값 (또는 다른 값)에서 열거 형을 조회하고 싶습니다. 다음 코드를 시도했지만 초기화 프로그램에서 정적을 허용하지 않습니다. 간단한 방법이 있습니까?
public enum Verbosity {
BRIEF, NORMAL, FULL;
private static Map<String, Verbosity> stringMap = new HashMap<String, Verbosity>();
private Verbosity() {
stringMap.put(this.toString(), this);
}
public static Verbosity getVerbosity(String key) {
return stringMap.get(key);
}
};
답변
valueOf
각 Enum에 대해 자동으로 생성되는 방법을 사용하십시오 .
Verbosity.valueOf("BRIEF") == Verbosity.BRIEF
임의의 값으로 시작 :
public static Verbosity findByAbbr(String abbr){
for(Verbosity v : values()){
if( v.abbr().equals(abbr)){
return v;
}
}
return null;
}
프로파일 러가 지시하는 경우 나중에 맵 구현으로 이동하십시오.
나는 그것이 모든 값을 반복한다는 것을 알고 있지만 3 개의 열거 형 값만으로는 다른 노력을 기울일 가치가 거의 없습니다.
답변
당신은 가까이 있습니다. 임의의 값을 얻으려면 다음과 같이 시도하십시오.
public enum Day {
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
// Reverse-lookup map for getting a day from an abbreviation
private static final Map<String, Day> lookup = new HashMap<String, Day>();
static {
for (Day d : Day.values()) {
lookup.put(d.getAbbreviation(), d);
}
}
private Day(String abbreviation) {
this.abbreviation = abbreviation;
}
public String getAbbreviation() {
return abbreviation;
}
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
}
}
답변
Java 8을 사용하면 다음과 같이 얻을 수 있습니다.
public static Verbosity findByAbbr(final String abbr){
return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}
답변
@ Lyle의 대답은 다소 위험하며 열거 형을 정적 내부 클래스로 만들면 특히 효과적이지 않습니다. 대신 나는 열거 형 전에 BootstrapSingleton 맵을로드하는 이와 같은 것을 사용했습니다.
편집 이 더 이상 현대의 JVM (JVM 1.6 이상)에 문제가되지 않습니다하지만 난 JRebel 문제가 여전히 있다고 생각 할 수 있지만 재검사 그것에 기회가 없었어요 .
먼저로드
public final class BootstrapSingleton {
// Reverse-lookup map for getting a day from an abbreviation
public static final Map<String, Day> lookup = new HashMap<String, Day>();
}
이제 열거 형 생성자에로드하십시오.
public enum Day {
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
private Day(String abbreviation) {
this.abbreviation = abbreviation;
BootstrapSingleton.lookup.put(abbreviation, this);
}
public String getAbbreviation() {
return abbreviation;
}
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
}
}
내부 열거 형이있는 경우 열거 형 정의 위에 맵을 정의 할 수 있으며 이론상으로로드해야합니다.
답변
그리고 valueOf () 사용할 수 없습니다 ?
편집 : Btw, 열거 형에서 정적 {}을 사용하지 못하게하는 것은 없습니다.
답변
다른 사람들에게 도움이되는 경우 여기에 나열되지 않은 선호하는 옵션은 Guava의지도 기능을 사용 합니다 .
public enum Vebosity {
BRIEF("BRIEF"),
NORMAL("NORMAL"),
FULL("FULL");
private String value;
private Verbosity(final String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
private static ImmutableMap<String, Verbosity> reverseLookup =
Maps.uniqueIndex(Arrays.asList(Verbosity.values()), Verbosity::getValue);
public static Verbosity fromString(final String id) {
return reverseLookup.getOrDefault(id, NORMAL);
}
}
기본 사용하면 사용할 수 있습니다 null
수행 할 수 있습니다, throw IllegalArgumentException
또는 당신이 fromString
를 반환 할 수 Optional
원하는대로 행동.
답변
Java 8부터 정적 블록없이 한 줄로 맵을 초기화 할 수 있습니다
private static Map<String, Verbosity> stringMap = Arrays.stream(values())
.collect(Collectors.toMap(Enum::toString, Function.identity()));