说我有一个枚举

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

我想找到一个字符串的枚举值,例如"A"就是Blah.A 怎么可能做到这一点?

Enum.valueOf()是我需要的方法吗? 如果是这样,我将如何使用它?


#1楼

这是我使用的一个漂亮的实用程序:

/*** 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我不能对Enum.valueOf使用T.class


#2楼

如果您不想编写自己的实用程序,请使用Google的guava库:

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

与内置的Java函数不同,它让您检查Bl中是否存在A且不引发异常。


#3楼

使用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();}
}

#4楼

为了增加以前的答案,并解决有关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的更多信息: https : //code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional


#5楼

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"


#6楼

如果文本与枚举值不同,则另一种解决方案:

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;}
}

#7楼

您可能需要这样做:

public enum ObjectType {PERSON("Person");public String parameterName;ObjectType(String parameterName) {this.parameterName = parameterName;}public String getParameterName() {return this.parameterName;}//From String method will return you the Enum for the provided input stringpublic 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”,它将返回枚举值,即“ Person”


#8楼

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;}}

#9楼

Apache的commons-lang库有一个静态函数org.apache.commons.lang3.EnumUtils.getEnum ,它将一个String映射到您的Enum类型。 答案基本上与Geoffreys相同,但是为什么当它已经在野外出现时却要自己动手做。


#10楼

另一个以相反方式捕获的实用程序。 使用标识该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中的final和static方法。 如果Foo拥有的不是公开的,不是最终的且不是静态的方法,例如getTranslate返回“ drei”,则可以使用其他方法: EnumUtil.from(Foo.class, "drei", "getTranslate")


#11楼

使用有效Java的 Joshua Bloch提供的模式:

(为简化起见)

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(),instance);}ENUM_MAP = Collections.unmodifiableMap(map);}public static MyEnum get (String name) {return ENUM_MAP.get(name);}
}

另请参阅:

使用实例枚举和映射的Oracle Java示例

Enum类型的静态块的执行顺序

如何从其String值查找Java枚举


#12楼

我喜欢使用这种过程将命令作为字符串解析为枚举。 我通常将其中一个枚举称为“未知”,因此在未找到其他枚举(即使在不区分大小写的基础上)而不是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;
}

#13楼

加上评分最高的答案,并提供有用的实用程序...

valueOf()不喜欢其输入,则会引发两个不同的Exception。

  • IllegalArgumentException
  • NullPointerExeption

如果您的要求不能保证您的String一定与枚举值匹配,例如,如果String数据来自数据库并且可能包含旧版本的枚举,则需要处理这些经常...

因此,这是我编写的可重用方法,该方法允许我们定义默认的Enum(如果我们传递的String不匹配则返回)。

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.THINGTWOvalueOf("THINGZERO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGONE
}

#14楼

在Java 8中,静态Map模式更加简单,这是我的首选方法。 如果要与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@Overridepublic String toString() {return value;}public static MyEnumForJson fromValue(String value){return MAP.get(value);}
}

#15楼

我在这里的2美分:使用Java8流+检查确切的字符串:

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批注中转换类型

#16楼

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

#17楼

关于什么?

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

#18楼

由于尚未提及switch -version,因此我对其进行了介绍(重用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;}}}

通过提供默认值,我们保持Enum.valueOf(String name)的约定 ,而不会以任何情况都不会返回null方式引发IllegalArgumentException 。 因此,如果名称为null ,则抛出NullPointerException如果default null defaultValue则抛出NullPointerException 。 这就是valueOfOrDefault工作方式。

此方法采用Map Map.getOrDefault(Object key, V defaultValue)的设计,该接口从Java 8开始提供Map.getOrDefault(Object key, V defaultValue)方法。


#19楼

获取枚举名称的最快方法是在应用程序启动时创建枚举文本和值的映射,并通过函数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.toString());}}public static String getEnumName(String text) {return map.get(text.toLowerCase());}
}

#20楼

枚举非常有用,我经常使用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");

#21楼

是的, Blah.valueOf("A")将给您Blah.A

请注意,名称必须完全匹配,包括大小写: Blah.valueOf("a")Blah.valueOf("A ")都抛出IllegalArgumentException

静态方法valueOf()values()在编译时创建,并且不会出现在源代码中。 但是,它们确实出现在Javadoc中。 例如, Dialog.ModalityType显示两个方法。


#22楼

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;
}

#23楼

使用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 B  B

灵感: Java中Enum的10个示例


#24楼

这是一种可以对任何枚举执行此操作的方法,并且不区分大小写。

/** * 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()));
}

#25楼

您还应该谨慎对待自己的情况。 让我解释一下:做Blah.valueOf("A")可以,但是Blah.valueOf("a")不能。 然后再次使用Blah.valueOf("a".toUpperCase(Locale.ENGLISH))

编辑
改变toUpperCasetoUpperCase(Locale.ENGLISH)基于TC。 注释和Java文档

EDIT2在Android上,你应该使用Locale.US ,作为sulai指出 。


#26楼

最好使用Blah.valueOf(string) ,但也可以使用Enum.valueOf(Blah.class, string)

如何从Java中的字符串值获取枚举值?相关推荐

  1. java 枚举值属性_java – 如何从属性获取枚举值

    我有一个值为VALID和INVALID的枚举,它具有与之关联的布尔属性.我想根据我提供的布尔值获取枚举值. 如果确实如此,我应该获得VALID,如果是,我应该获得INVALID.我想基于成员变量的值, ...

  2. [转载] Java中的字符串处理

    参考链接: Java中的StringBuffer appendCodePoint()方法以及示例 JDK8在线Api中文手册 JDK8在线Api英文手册 Java中的字符串处理 1.1 String类 ...

  3. Java中的字符串串联

    String Concatenation in java is very common. Being a Java developer, you are aware that every once i ...

  4. Java中的字符串程序

    String is the most widely used class in java programming. That's why String programs are used in jav ...

  5. java中判断字符串实际长度(中文2个字符,英文1个字符)的方法,包含中英文符号

    java中判断字符串实际长度(中文2个字符,英文1个字符)的方法,包含中英文符号 介绍 数据库中很多字段都会限制长度,为了方便用户使用,在前端界面给出限制长度的提示,看网上很多写的获取字符串长度都没有 ...

  6. Java中的字符串驻留

    转自:http://www.cdtarena.com/javapx/201307/9088.html 最近在工作的时候,一句再正常不过的代码String a = "hello" + ...

  7. 图说:为什么Java中的字符串被定义为不可变的

    转载自 图说:为什么Java中的字符串被定义为不可变的 字符串,想必大家最熟悉不过了,通常我们在代码中有几种方式可以创建字符串,比如:String s = "Hollis";这时, ...

  8. java 调用linux 脚本并获取返回值

    大家好,我是烤鸭: 今天分享下java 调用 shell脚本 并获取返回值. 代码实践 String cmd = "df -h"; StringBuffer sb = new St ...

  9. java中如果需要返回多个值怎么办

    Java中如果需要返回多个值怎么办 首先我们明确一下:java方法的返回值只有一个,但是返回值的类型不限 有一种编程语言可以返回多个值 Python,实例如下:  运行结果如下: [whuang@hu ...

最新文章

  1. double类型数值计算出现误差的解决办法
  2. typora插入代码设置_Typora基本功能介绍
  3. 2引擎帮助文档_使用Sentence Transformers和Faiss构建语义搜索引擎
  4. 这4点教你找到小程序专业开发公司
  5. java 对象赋值给scala_将Scala变量转换为Java对象… varargs
  6. HDOJ--1495--非常可乐(隐式图)
  7. kettle将文件路径定义为_Kettle变量和自己定义java代码的实例应用
  8. mysql基于时间盲注_MySQL基于时间盲注(Time-Based Blind SQL Injection)五种延时方法...
  9. html打开显示不全,打开浏览器网页显示不全 网页显示不正常解决方法
  10. 基金业绩的python分析_DFQ2018绩效归因与基金投资分析工具.pdf
  11. 怎样查看对方计算机网络密码,如何查看邻居家的wifi密码?不知道wifi密码怎么蹭网...
  12. JS实现图片不存在时显示默认图片
  13. 1,标准差的计算 2,标准分数z-score
  14. mysql转储导入错误_将MySQL转储应用于RDS时出现“无法解析表名”错误
  15. 企业应如何运用ERP系统的BOM表?
  16. 影响信用贷款的四大条件
  17. 安卓bmi项目_BMI计算器安卓版下载
  18. 机敏问答[复变][5] #20210629
  19. 【目标识别】--【截图程序】海康摄像头sdk二次开发自动多摄像头截图程序
  20. 3dmaxobj导出选项_3dmax导出obj没有贴图该怎么办

热门文章

  1. 第六周项目一-分数类的雏形(1)
  2. studio添加依赖工程方法
  3. 线程池之SingleThreadPool学习
  4. 【Android基础】从属性动画看代码设计的艺术
  5. java gui 项目解密,java GUI(实例小项目--列出磁盘目录)
  6. 解锁UI自动化新姿势-UI Recorder
  7. 使用PHPStorm 配置自定义的Apache与PHP环境
  8. 数値の切捨て、切り上げ、四捨五入
  9. Java执行字符串中的运算公式
  10. oracle数据泵数据库导出导入及定时备份