0


如何从Java中的字符串值中获取枚举值

问:

说我有一个枚举,它只是

publicenumBlah{A,B,C,D}

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

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

答1:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

是的,Blah.valueOf(“A”) 会给您Blah.A。

请注意,名称必须是 exact 匹配,包括大小写:Blah.valueOf(“a”) 和 Blah.valueOf("A ") 都抛出 IllegalArgumentException。

静态方法 valueOf() 和 values() 在编译时创建,不会出现在源代码中。不过,它们确实出现在 Javadoc 中;例如,Dialog.ModalityType 显示了这两种方法。

作为参考,Blah.valueOf("A") 方法是区分大小写 并且不允许多余的空格,因此@JoséMi 在下面提出了替代解决方案。
@Michael Myers,由于这个答案是迄今为止投票最多的,我是否应该理解将枚举及其字符串值定义为完全相同的好习惯?
@KevinMeredith:如果您的意思是 toString() 值,不,我不会这么说。 name() 将为您提供枚举常量的实际定义名称,除非您覆盖它。
“在编译时创建并且不出现在源代码中”究竟是什么意思。 ?
@treesAreEverywhere 更具体地说,这些方法由编译器生成(或synthesized)。实际的 enum Blah {...} 定义不应尝试声明自己的 values 或 valuesOf。这就像您如何编写“AnyTypeName.class”,即使您从未真正声明过“类”成员变量;编译器使这一切都可以正常工作。 (此答案可能在 3 个月后对您不再有用,但以防万一。)

答2:

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

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

publicenumBlah{A("text1"),B("text2"),C("text3"),D("text4");privateString text;Blah(String text){this.text = text;}publicStringgetText(){returnthis.text;}publicstaticBlahfromString(String text){for(Blah b :Blah.values()){if(b.text.equalsIgnoreCase(text)){return b;}}returnnull;}}
throw new IllegalArgumentException("No constant with text " + text + " found") 会比 return null 更好。
@Sangdol 通常检查 SUN - 哎呀 - Oracle 在相同情况下所做的事情是一件好事。正如 Enum.valueOf() 所展示的那样,IS 是在这种情况下抛出异常的最佳实践。 因为这是一种特殊情况。 “性能优化”是编写不可读代码的糟糕借口;-)

答3:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

使用来自 Joshua Bloch 的模式,Effective Java:

(为简洁而简化)

enumMyEnum{ENUM_1("A"),ENUM_2("B");privateString name;privatestaticfinalMapENUM_MAP;MyEnum(String name){this.name = name;}publicStringgetName(){returnthis.name;}// Build an immutable map of String name to enum pairs.// Any Map impl can be used.static{Map map =newConcurrentHashMap();for(MyEnum instance :MyEnum.values()){
            map.put(instance.getName().toLowerCase(),instance);}ENUM_MAP=Collections.unmodifiableMap(map);}publicstaticMyEnum get (String name){returnENUM_MAP.get(name.toLowerCase());}}

另见:

Oracle Java Example using Enum and Map of instances

Execution order of of static blocks in an Enum type

How can I lookup a Java enum from its String value

这在 Java 8 中甚至更简单,因为您可以这样做:Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity()))我还建议覆盖 toString()(通过构造函数传入)并使用它而不是名称,特别是如果 Enum 与可序列化数据相关联,因为这可以让您控制套管没有给声纳一个合适的。
Static initialization is inherently synchronized,因此绝对没有理由在此处使用 ConcurrentHashMap,因为在初始化后地图永远不会被修改。因此,甚至例如 JLS 中的示例本身也使用常规 HashMap。

答4:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

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

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

然后在我的枚举类中,我通常有这个来节省一些打字:

publicstaticMyEnumfromString(String name){returngetEnumFromString(MyEnum.class, name);}

如果您的枚举不是全部大写,只需更改 Enum.valueOf 行。

太糟糕了,我不能将 T.class 用于 Enum.valueOf,因为 T 已被删除。

那个空的 catch 块真的让我发疯了,对不起。
@LazloBonin:异常是针对异常情况,而不是针对控制流。为自己获取一份 Effective Java。
可怕!始终,始终捕获可以处理的异常。上面的例子是一个如何不做的完美例子。为什么?所以它返回 NULL,然后调用者必须检查 NULL 或抛出 NPE。如果调用者知道如何处理这种情况,那么执行 if 与 try-catch 可能看起来更优雅,但如果他无法处理,他必须再次传递 null 并且调用者的调用者必须再次检查 NULL等等等等。
@whiskeysierra 我知道对 Java 或软件开发充满热情是一回事,但你得冷静一下。像这样出人头地/成为额外的人没有任何好处。
返回 Optional 而不是 nullable 怎么样?

答5:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

你也应该小心你的情况。让我解释一下:做 Blah.valueOf(“A”) 行,但 Blah.valueOf(“a”) 行不通。然后再次 Blah.valueOf(“a”.toUpperCase(Locale.ENGLISH)) 将工作。

在 Android 上,您应该使用 Locale.US,作为 sulai points out。

请注意默认语言环境!

答6:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

在 Java 8 或更高版本中,使用 Streams:

publicenumBlah{A("text1"),B("text2"),C("text3"),D("text4");privateString text;Blah(String text){this.text = text;}publicStringgetText(){returnthis.text;}publicstaticOptionalfromText(String text){returnArrays.stream(values()).filter(bl -> bl.text.equalsIgnoreCase(text)).findFirst();}}
Java 8 做了一些好事,虽然我喜欢 Streams(主要用于并发)......这实际上不是使用它们的理由。它什么都不买 OP 并且性能更差......只需将所有项目的 for/next 循环替换为相同的 Stream 版本(甚至不是并行)。对于一些条目......谁在乎但要清楚,这不是一些“因为Java 8而更好”的例子。它只是返回 Optional vs null 的流利风格的绿色与蓝色“不同”实现(并且流利风格需要所有连接方法的非空返回)。

答7:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

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

/** 
 * Finds the value of the given enumeration by name, case-insensitive. 
 * Throws an IllegalArgumentException if no match is found.  
 **/publicstatic>TvalueOfIgnoreCase(Class enumeration,String name){for(T enumValue : enumeration.getEnumConstants()){if(enumValue.name().equalsIgnoreCase(name)){return enumValue;}}thrownewIllegalArgumentException(String.format("There is no value with name '%s' in Enum %s",
        name, enumeration.getName()));}
很好地使用泛型,但不确定 IllegalArgumentException 是否真的是正确的合同。首先,查找失败完全有可能(并且预期?)......它本身不在集合中(实际上是枚举)。抛出 RuntimeException “在方法外传播 [s]”。由于这不在方法签名中 - 调用者不会期望它。最好使用 Map 构造(在未找到时返回 null)或者甚至更好... Optional.empty()。

答8:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

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

答9:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

我的两分钱:使用 Java 8 Streams 并检查一个确切的字符串:

publicenumMyEnum{VALUE_1("Super"),VALUE_2("Rainbow"),VALUE_3("Dash"),VALUE_3("Rocks");privatefinalString value;MyEnum(String value){this.value = value;}/**
     * @return the Enum representation for the given string.
     * @throws IllegalArgumentException if unknown string.
     */publicstaticMyEnumfromString(String s)throwsIllegalArgumentException{returnArrays.stream(MyEnum.values()).filter(v -> v.value.equals(s)).findFirst().orElseThrow(()->newIllegalArgumentException("unknown value: "+ s));}}

我将该函数重命名为 fromString(),因为使用该约定命名它,您将从 Java 语言本身获得一些好处;例如:

在 HeaderParam 注解处直接转换类型

答10:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

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

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

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

答11:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

您可能需要这样做:

publicenumObjectType{PERSON("Person");publicString parameterName;ObjectType(String parameterName){this.parameterName = parameterName;}publicStringgetParameterName(){returnthis.parameterName;}// From the String method, it will return you the Enum for the provided input stringpublicstaticObjectTypefromString(String parameterName){if(parameterName !=null){for(ObjectType objType :ObjectType.values()){if(parameterName.equalsIgnoreCase(objType.parameterName)){return objType;}}}returnnull;}}

又多了一个

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

这将通过字符串化枚举名称返回值。例如,如果您在 fromEnumName 中提供“PERSON”,它将返回 Enum 的值,即“Person”。

原文链接:https://www.huntsbot.com/qa/07Xd/how-to-get-an-enum-value-from-a-string-value-in-java?lang=zh_CN&from=csdn

huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求


本文转载自: https://blog.csdn.net/kalman2019/article/details/128609998
版权归原作者 HuntsBot 所有, 如有侵权,请联系我们删除。

“如何从Java中的字符串值中获取枚举值”的评论:

还没有评论