问:

说我有一个枚举,它只是

public enum Blah {

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+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

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

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;

}

}

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:

(为简洁而简化)

enum MyEnum {

ENUM_1("A"),

ENUM_2("B");

private String name;

private static final Map 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 map = new ConcurrentHashMap();

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

}

}

另见:

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

*/

public static > T getEnumFromString(Class 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.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:

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 fromText(String text) {

return Arrays.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.

**/

public static > T valueOfIgnoreCase(

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

));

}

很好地使用泛型,但不确定 IllegalArgumentException 是否真的是正确的合同。首先,查找失败完全有可能(并且预期?)......它本身不在集合中(实际上是枚举)。抛出 RuntimeException “在方法外传播 [s]”。由于这不在方法签名中 - 调用者不会期望它。最好使用 Map 构造(在未找到时返回 null)或者甚至更好... Optional.empty()。

答8:

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

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

答9:

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

我的两分钱:使用 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 语言本身获得一些好处;例如:

在 HeaderParam 注解处直接转换类型

答10:

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

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

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

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

答11:

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

您可能需要这样做:

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”。

原文链接: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+任务平台外包需求

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: