[java] String 값에서 Java 열거 형을 어떻게 조회 할 수 있습니까?

문자열 값 (또는 다른 값)에서 열거 형을 조회하고 싶습니다. 다음 코드를 시도했지만 초기화 프로그램에서 정적을 허용하지 않습니다. 간단한 방법이 있습니까?

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()));