etc./StackOverFlow

Java의 문자열 값에서 열거형 값을 얻는 방법

청렴결백한 만능 재주꾼 2021. 11. 30. 23:59
반응형

질문자 :Malachi


내가 열거 형을 가지고 있다고 가정 해보십시오.

 public enum Blah { A, B, C, D }

그리고 문자열의 열거형 값을 찾고 싶습니다. 예를 들어 "A" Blah.A 가 될 것입니다. 어떻게 이런 일이 가능할까요?

Enum.valueOf() 가 필요한 방법입니까? 그렇다면 이것을 어떻게 사용할까요?



예, Blah.valueOf("A") Blah.A 를 제공합니다.

이름은 대소문자를 포함 하여 정확히 Blah.valueOf("a")Blah.valueOf("A ") 둘 다 IllegalArgumentException 던집니다.

정적 메서드 valueOf()values() 는 컴파일 타임에 생성되며 소스 코드에 나타나지 않습니다. 그러나 그들은 Javadoc에 나타납니다. 예를 들어 Dialog.ModalityType 은 두 가지 방법을 모두 보여줍니다.


Michael Myers

텍스트가 열거형 값과 동일하지 않은 경우 다른 솔루션:

 public enum Blah { A("text1"), B("text2"), C("text3"), D("text4"); private String text; Blah(String text) { this.text = text; } public String getText() { return this.text; } public static Blah fromString(String text) { for (Blah b : Blah.values()) { if (b.text.equalsIgnoreCase(text)) { return b; } } return null; } }

JoséMi

Joshua Bloch , Effective Java 의 패턴을 사용하십시오.

(간단함을 위해 단순화)

 enum MyEnum { ENUM_1("A"), ENUM_2("B"); private String name; private static final Map<String,MyEnum> ENUM_MAP; MyEnum (String name) { this.name = name; } public String getName() { return this.name; } // Build an immutable map of String name to enum pairs. // Any Map impl can be used. static { Map<String,MyEnum> map = new ConcurrentHashMap<String, MyEnum>(); for (MyEnum instance : MyEnum.values()) { map.put(instance.getName().toLowerCase(),instance); } ENUM_MAP = Collections.unmodifiableMap(map); } public static MyEnum get (String name) { return ENUM_MAP.get(name.toLowerCase()); } }

또한 다음을 참조하십시오.

인스턴스의 Enum 및 Map을 사용하는 Oracle Java 예제

Enum 유형의 정적 블록 실행 순서

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


Darrell Teague

내가 사용하는 멋진 유틸리티는 다음과 같습니다.

 /** * A common method for all enums since they can't have another base class * @param <T> Enum type * @param c enum type. All enums must be all caps. * @param string case insensitive * @return corresponding enum, or null */ public static <T extends Enum<T>> T getEnumFromString(Class<T> c, String string) { if( c != null && string != null ) { try { return Enum.valueOf(c, string.trim().toUpperCase()); } catch(IllegalArgumentException ex) { } } return null; }

그런 다음 내 열거형 클래스에는 일반적으로 입력을 저장하기 위해 다음이 있습니다.

 public static MyEnum fromString(String name) { return getEnumFromString(MyEnum.class, name); }

열거형이 모두 대문자가 아닌 경우 Enum.valueOf 행을 변경하기만 하면 됩니다.

T 가 지워 Enum.valueOf T.class 에 T.class를 사용할 수 없다는 것이 너무 나쁩니다.


Geoffrey Zheng

케이스도 조심해야 합니다. 설명하겠습니다. Blah.valueOf("A") 는 작동하지만 Blah.valueOf("a") 는 작동하지 않습니다. 그런 다음 다시 Blah.valueOf("a".toUpperCase(Locale.ENGLISH)) 가 작동합니다.

Android에서는 sulai가 지적한 Locale.US 를 사용해야 합니다.


João Portela

Java 8 이상에서 Streams 사용:

 public enum Blah { A("text1"), B("text2"), C("text3"), D("text4"); private String text; Blah(String text) { this.text = text; } public String getText() { return this.text; } public static Optional<Blah> fromText(String text) { return Arrays.stream(values()) .filter(bl -> bl.text.equalsIgnoreCase(text)) .findFirst(); } }

Hans Schreuder

다음은 모든 Enum에 대해 수행할 수 있고 대소문자를 구분하지 않는 방법입니다.

 /** * Finds the value of the given enumeration by name, case-insensitive. * Throws an IllegalArgumentException if no match is found. **/ public static <T extends Enum<T>> T valueOfIgnoreCase( Class<T> enumeration, String name) { for (T enumValue : enumeration.getEnumConstants()) { if (enumValue.name().equalsIgnoreCase(name)) { return enumValue; } } throw new IllegalArgumentException(String.format( "There is no value with name '%s' in Enum %s", name, enumeration.getName() )); }

Patrick Arnesen

Blah.valueOf(string) 것이 가장 Enum.valueOf(Blah.class, string) 를 사용할 수도 있습니다.


Peter Lawrey

여기 내 두 센트 : Java 8 Streams를 사용하고 정확한 문자열을 확인하십시오.

 public enum MyEnum { VALUE_1("Super"), VALUE_2("Rainbow"), VALUE_3("Dash"), VALUE_3("Rocks"); private final String value; MyEnum(String value) { this.value = value; } /** * @return the Enum representation for the given string. * @throws IllegalArgumentException if unknown string. */ public static MyEnum fromString(String s) throws IllegalArgumentException { return Arrays.stream(MyEnum.values()) .filter(v -> v.value.equals(s)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("unknown value: " + s)); } }

해당 규칙을 사용하여 이름을 지정한 이후로 함수 이름을 fromString() 변경했습니다. Java 언어 자체에서 몇 가지 이점을 얻을 수 있습니다. 예를 들어:

  1. HeaderParam 주석에서 유형의 직접 변환

Manu

자체 유틸리티를 작성하지 않으려면 Google의 라이브러리를 사용하세요.

 Enums.getIfPresent(Blah.class, "A")

내장된 Java 함수와 달리 Blah에 A가 있고 예외를 throw하지 않는지 확인할 수 있습니다.


Andrejs

다음이 필요할 수 있습니다.

 public enum ObjectType { PERSON("Person"); public String parameterName; ObjectType(String parameterName) { this.parameterName = parameterName; } public String getParameterName() { return this.parameterName; } // From the String method, it will return you the Enum for the provided input string public static ObjectType fromString(String parameterName) { if (parameterName != null) { for (ObjectType objType : ObjectType.values()) { if (parameterName.equalsIgnoreCase(objType.parameterName)) { return objType; } } } return null; } }

하나 더 추가

 public static String fromEnumName(String parameterName) { if (parameterName != null) { for (DQJ objType : DQJ.values()) { if (parameterName.equalsIgnoreCase(objType.name())) { return objType.parameterName; } } } return null; }

이렇게 하면 문자열화된 열거형 이름으로 값이 반환됩니다. 예를 들어 fromEnumName에 "PERSON"을 제공하면 Enum 값, 즉 "Person"이 반환됩니다.


Murtaza Kanchwala

이를 수행하는 또 다른 방법은 Enum name() name 은 제공된 문자열을 확인하는 데 사용할 수 있는 열거형을 만드는 데 사용된 정확한 문자열을 반환합니다.

 public enum Blah { A, B, C, D; public static Blah getEnum(String s){ if(A.name().equals(s)){ return A; }else if(B.name().equals(s)){ return B; }else if(C.name().equals(s)){ return C; }else if (D.name().equals(s)){ return D; } throw new IllegalArgumentException("No Enum specified for this string"); } }

테스트:

 System.out.println(Blah.getEnum("B").name()); // It will print BB

영감: Java에서 Enum의 10가지 예


Vikram

다음은 Guava 라이브러리를 사용하는 솔루션입니다. getPlanet() 메서드는 대소문자를 구분하지 않으므로 getPlanet("MerCUrY")은 Planet.MERCURY를 반환합니다.

 package com.universe.solarsystem.planets; import org.apache.commons.lang3.StringUtils; import com.google.common.base.Enums; import com.google.common.base.Optional; //Pluto and Eris are dwarf planets, who cares! public enum Planet { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE; public static Planet getPlanet(String name) { String val = StringUtils.trimToEmpty(name).toUpperCase(); Optional <Planet> possible = Enums.getIfPresent(Planet.class, val); if (!possible.isPresent()) { throw new IllegalArgumentException(val + "? There is no such planet!"); } return possible.get(); } }

javabrew

열거형은 매우 유용합니다. 다음 예제와 같이 다른 언어로 된 일부 필드에 대한 설명을 추가하기 위해 Enum 을 많이 사용했습니다.

 public enum Status { ACT(new String[] { "Accepted", "مقبول" }), REJ(new String[] { "Rejected", "مرفوض" }), PND(new String[] { "Pending", "في الانتظار" }), ERR(new String[] { "Error", "خطأ" }), SNT(new String[] { "Sent", "أرسلت" }); private String[] status; public String getDescription(String lang) { return lang.equals("en") ? status[0] : status[1]; } Status(String[] status) { this.status = status; } }

getDescription(String lang) 메서드에 전달된 언어 코드를 기반으로 설명을 동적으로 검색할 수 있습니다. 예를 들면 다음과 같습니다.

 String statusDescription = Status.valueOf("ACT").getDescription("en");

Ebraheem Alrabeea

Java 8에서는 정적 맵 패턴이 훨씬 더 쉽고 내가 선호하는 방법입니다. Jackson과 함께 Enum을 사용하려면 toString을 재정의하고 이름 대신 사용하고 @JsonValue

 public enum MyEnum { BAR, BAZ; private static final Map<String, MyEnum> MAP = Stream.of(MyEnum.values()).collect(Collectors.toMap(Enum::name, Function.identity())); public static MyEnum fromName(String name){ return MAP.get(name); } } public enum MyEnumForJson { BAR("bar"), BAZ("baz"); private static final Map<String, MyEnumForJson> MAP = Stream.of(MyEnumForJson.values()).collect(Collectors.toMap(Object::toString, Function.identity())); private final String value; MyEnumForJson(String value) { this.value = value; } @JsonValue @Override public String toString() { return value; } public static MyEnumForJson fromValue(String value){ return MAP.get(value); } }

Novaterata

이전 답변에 추가하고 null 및 NPE에 대한 일부 토론을 다루기 위해 Guava Optionals 를 사용하여 부재/유효하지 않은 경우를 처리하고 있습니다. 이것은 URI 및 매개변수 구문 분석에 유용합니다.

 public enum E { A,B,C; public static Optional<E> fromString(String s) { try { return Optional.of(E.valueOf(s.toUpperCase())); } catch (IllegalArgumentException|NullPointerException e) { return Optional.absent(); } } }

모르는 사람들을 위해 Optional 을 사용 하여 null을 방지하는 방법에 대한 추가 정보가 있습니다.


tom

public static MyEnum getFromValue(String value) { MyEnum resp = null; MyEnum nodes[] = values(); for(int i = 0; i < nodes.length; i++) { if(nodes[i].value.equals(value)) { resp = nodes[i]; break; } } return resp; }

Prasobh.Kollattu

해시맵을 사용하는 Thrift 생성 코드에서 영감을 받은 O(1) 메서드입니다.

 public enum USER { STUDENT("jon",0),TEACHER("tom",1); private static final Map<String, Integer> map = new HashMap<>(); static { for (USER user : EnumSet.allOf(USER.class)) { map.put(user.getTypeName(), user.getIndex()); } } public static int findIndexByTypeName(String typeName) { return map.get(typeName); } private USER(String typeName,int index){ this.typeName = typeName; this.index = index; } private String typeName; private int index; public String getTypeName() { return typeName; } public void setTypeName(String typeName) { this.typeName = typeName; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } }

Sisyphus

Apache의 commons-lang 라이브러리에는 String을 Enum 유형에 매핑하는 정적 함수 org.apache.commons.lang3.EnumUtils.getEnum이 있습니다. 본질적으로 Geoffrey Zheng's 와 동일한 답변이지만 이미 야생에 있을 때 자신을 굴릴 필요가 없습니다.


pjklauser

사용하다:

 public enum MyEnum { FIRST, SECOND, THIRD; public static Optional<MyEnum> fromString(String value) { try { return Optional.of(MyEnum.valueOf(value)); }catch(Exception e) { return Optional.empty(); } } }

DCO

java.lang.Enum 은 Java의 모든 열거 유형에 사용할 수 있는 몇 가지 유용한 메소드를 정의합니다.

  • name() 메서드를 사용하여 Enum 상수의 이름을 가져올 수 있습니다. 열거형 상수를 작성하는 데 사용되는 문자열 리터럴은 해당 이름입니다.
  • 마찬가지로 values() 메서드를 사용하여 Enum 유형에서 모든 Enum 상수의 배열을 가져올 수 있습니다.
  • 그리고 질문에 대해 valueOf() 메서드를 사용하여 아래와 같이 Java에서 String을 Enum 상수로 변환할 수 있습니다.
 public class EnumDemo06 { public static void main(String args[]) { Gender fromString = Gender.valueOf("MALE"); System.out.println("Gender.MALE.name() : " + fromString.name()); } private enum Gender { MALE, FEMALE; } } Output: Gender.MALE.name() : MALE

이 코드 스니펫에서 valueOf() 메서드는 Enum 상수인 Gender.MALE 를 반환하고 이에 대한 호출 이름은 "MALE" 를 반환합니다.


KNU

유용한 유틸리티와 함께 Michael Myers의 답변 에 추가 ...

valueOf() 는 입력이 마음에 들지 않는 경우 두 가지 다른 예외를 throw합니다.

  • IllegalArgumentException
  • NullPointerExeption

요구 사항이 문자열이 열거형 값과 확실히 일치한다는 보장이 없는 경우(예: 문자열 데이터가 데이터베이스에서 제공되고 열거형의 이전 버전을 포함할 수 있는 경우) 다음을 처리해야 합니다. 자주...

그래서 여기에 우리가 전달한 문자열이 일치하지 않을 경우 반환될 기본 Enum을 정의할 수 있는 재사용 가능한 메서드가 있습니다.

 private static <T extends Enum<T>> T valueOf( String name , T defaultVal) { try { return Enum.valueOf(defaultVal.getDeclaringClass() , name); } catch (IllegalArgumentException | NullPointerException e) { return defaultVal; } }

다음과 같이 사용하십시오.

 public enum MYTHINGS { THINGONE, THINGTWO } public static void main(String [] asd) { valueOf("THINGTWO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGTWO valueOf("THINGZERO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGONE }

lance.dolan

switch 이 아직 언급되지 않았으므로 소개합니다(OP의 열거형 재사용).

 private enum Blah { A, B, C, D; public static Blah byName(String name) { switch (name) { case "A": return A; case "B": return B; case "C": return C; case "D": return D; default: throw new IllegalArgumentException( "No enum constant " + Blah.class.getCanonicalName() + "." + name); } } }

valueOf(String name) 메서드에 추가 값을 제공하지 않으므로 다른 동작을 원할 경우에만 추가 메서드를 정의하는 것이 좋습니다. IllegalArgumentException 을 발생시키고 싶지 않다면 구현을 다음과 같이 변경할 수 있습니다.

 private enum Blah { A, B, C, D; public static Blah valueOfOrDefault(String name, Blah defaultValue) { switch (name) { case "A": return A; case "B": return B; case "C": return C; case "D": return D; default: if (defaultValue == null) { throw new NullPointerException(); } return defaultValue; } } }

기본값을 제공함으로써 null 이 반환되지 않는 방식으로 IllegalArgumentException 을 던지지 않고 Enum.valueOf(String name) 의 계약 을 유지합니다. 따라서 이름이 null NullPointerException 을 throw하고 defaultValuenull default 발생합니다. 이것이 valueOfOrDefault 작동하는 방식입니다.

이 접근 방식은 Java 8에서 Map.getOrDefault(Object key, V defaultValue) 메서드를 제공하는 Map -Interface의 디자인을 채택합니다.


LuCio

나는 그 값(텍스트가 아님)이 아닌 "blah" 이름을 찾기 위한 답을 찾고 있었습니다. Manu의 답변을 기반으로 이 코드가 유용하다는 것을 알았습니다.

 public enum Blah { A("text1"), B("text2"), C("text3"), D("text4"); private String text; Blah(String text) { this.text = text; } public String getText() { return this.text; } public static Blah valueOfCode(String blahCode) throws IllegalArgumentException { Blah blah = Arrays.stream(Blah.values()) .filter(val -> val.name().equals(blahCode)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Unable to resolve blah: " + blahCode)); return blah; }

}


orly.sharon

역방향으로 캡처하는 또 다른 유틸리티입니다. 이름이 아닌 해당 Enum을 식별하는 값을 사용합니다.

 import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.EnumSet; public class EnumUtil { /** * Returns the <code>Enum</code> of type <code>enumType</code> whose a * public method return value of this Enum is * equal to <code>valor</code>.<br/> * Such method should be unique public, not final and static method * declared in Enum. * In case of more than one method in match those conditions * its first one will be chosen. * * @param enumType * @param value * @return */ public static <E extends Enum<E>> E from(Class<E> enumType, Object value) { String methodName = getMethodIdentifier(enumType); return from(enumType, value, methodName); } /** * Returns the <code>Enum</code> of type <code>enumType</code> whose * public method <code>methodName</code> return is * equal to <code>value</code>.<br/> * * @param enumType * @param value * @param methodName * @return */ public static <E extends Enum<E>> E from(Class<E> enumType, Object value, String methodName) { EnumSet<E> enumSet = EnumSet.allOf(enumType); for (E en : enumSet) { try { String invoke = enumType.getMethod(methodName).invoke(en).toString(); if (invoke.equals(value.toString())) { return en; } } catch (Exception e) { return null; } } return null; } private static String getMethodIdentifier(Class<?> enumType) { Method[] methods = enumType.getDeclaredMethods(); String name = null; for (Method method : methods) { int mod = method.getModifiers(); if (Modifier.isPublic(mod) && !Modifier.isStatic(mod) && !Modifier.isFinal(mod)) { name = method.getName(); break; } } return name; } }

예시:

 public enum Foo { ONE("eins"), TWO("zwei"), THREE("drei"); private String value; private Foo(String value) { this.value = value; } public String getValue() { return value; } }

EnumUtil.from(Foo.class, "drei") Foo.THREE 반환합니다 getValue 를 사용하여 "drei"와 일치시킬 것이기 때문입니다. 이것은 Foo에서 최종적이지 않고 정적 메소드가 아닌 고유한 공개입니다. getTranslate 와 같이 최종 및 정적 메서드가 아닌 public 이상의 메서드가 있는 경우 다른 메서드를 사용할 수 있습니다. EnumUtil.from(Foo.class, "drei", "getTranslate") .


Moesio

열거형 값()

열거형 클래스는 컴파일될 때 클래스의 정적 valueOf() 메서드를 자동으로 가져옵니다. valueOf() 메서드를 사용하여 주어진 String 값에 대한 열거형 클래스의 인스턴스를 얻을 수 있습니다.

예를 들어:

 public class Main { public static void main(String[] args) throws Exception { System.out.println(Strings.TWO.name()); } enum Strings { ONE, TWO, THREE } }

Nitya Nand Pandey

나는 이러한 종류의 프로세스를 사용하여 명령을 문자열로 열거형으로 구문 분석하는 것을 좋아합니다. 나는 일반적으로 열거형 중 하나를 "알 수 없음"으로 가지고 있으므로 null(값이 없음을 의미함)이 아니라 다른 열거형을 찾을 수 없을 때(대소문자를 구분하지 않는 경우에도) 반환하는 것이 도움이 됩니다. 따라서 이 접근 방식을 사용합니다.

 static <E extends Enum<E>> Enum getEnumValue(String what, Class<E> enumClass) { Enum<E> unknown=null; for (Enum<E> enumVal: enumClass.getEnumConstants()) { if (what.compareToIgnoreCase(enumVal.name()) == 0) { return enumVal; } if (enumVal.name().compareToIgnoreCase("unknown") == 0) { unknown=enumVal; } } return unknown; }

John Hemming

코틀린 솔루션

확장을 만든 다음 valueOf<MyEnum>("value") 를 호출합니다. 유형이 유효하지 않으면 null을 가져와 처리해야 합니다.

 inline fun <reified T : Enum<T>> valueOf(type: String): T? { return try { java.lang.Enum.valueOf(T::class.java, type) } catch (e: Exception) { null } }

valueOf<MyEnum>("value", MyEnum.FALLBACK) 호출하고 null 응답을 방지하여 기본값을 설정할 수 있습니다. 기본값이 자동이 되도록 특정 열거형을 확장할 수 있습니다.

 inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T { return try { java.lang.Enum.valueOf(T::class.java, type) } catch (e: Exception) { default } }

또는 둘 다 원하면 두 번째를 만드십시오.

 inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T = valueOf<T>(type) ?: default

Gibolt

열거형의 이름을 얻는 가장 빠른 방법은 응용 프로그램이 시작될 때 열거형 텍스트와 값의 맵을 만들고 이름을 얻으려면 Blah.getEnumName() 함수를 호출하는 것입니다.

 public enum Blah { A("text1"), B("text2"), C("text3"), D("text4"); private String text; private HashMap<String, String> map; Blah(String text) { this.text = text; } public String getText() { return this.text; } static{ createMapOfTextAndName(); } public static void createMapOfTextAndName() { map = new HashMap<String, String>(); for (Blah b : Blah.values()) { map.put(b.getText(),b.name()); } } public static String getEnumName(String text) { return map.get(text.toLowerCase()); } }

Bishal Jaiswal

Blah.valueOf("A") 는 찾고 있는 문이지만 이것은 CASE SENSITIVE 이므로 Blah.valueOf("a")가 작동하지 않고 예외를 생성한다는 점을 명심하십시오.


Numan Gillani

출처 : http:www.stackoverflow.com/questions/604424/how-to-get-an-enum-value-from-a-string-value-in-java

반응형