問:
說我有一個枚舉,它只是
public enum Blah {
A, B, C, D
}
我想找到一個字符串的枚舉值,例如 “A” 這將是 Blah.A。怎么可能做到這一點(diǎn)?
Enum.valueOf() 是我需要的方法嗎?如果是這樣,我將如何使用它?
答1:
保持自己快人一步,享受全網(wǎng)獨(dú)家提供的一站式外包任務(wù)、遠(yuǎn)程工作、創(chuàng)意產(chǎn)品訂閱服務(wù)–huntsbot.com
是的,Blah.valueOf(“A”) 會給您Blah.A。
請注意,名稱必須是 exact 匹配,包括大小寫:Blah.valueOf(“a”) 和 Blah.valueOf("A ") 都拋出 IllegalArgumentException。
靜態(tài)方法 valueOf() 和 values() 在編譯時創(chuàng)建,不會出現(xiàn)在源代碼中。不過,它們確實(shí)出現(xiàn)在 Javadoc 中;例如,Dialog.ModalityType 顯示了這兩種方法。
作為參考,Blah.valueOf("A") 方法是區(qū)分大小寫 并且不允許多余的空格,因此@JoséMi 在下面提出了替代解決方案。
@Michael Myers,由于這個答案是迄今為止投票最多的,我是否應(yīng)該理解將枚舉及其字符串值定義為完全相同的好習(xí)慣?
@KevinMeredith:如果您的意思是 toString() 值,不,我不會這么說。 name() 將為您提供枚舉常量的實(shí)際定義名稱,除非您覆蓋它。
“在編譯時創(chuàng)建并且不出現(xiàn)在源代碼中”究竟是什么意思。 ?
@treesAreEverywhere 更具體地說,這些方法由編譯器生成(或synthesized)。實(shí)際的 enum Blah {...} 定義不應(yīng)嘗試聲明自己的 values 或 valuesOf。這就像您如何編寫“AnyTypeName.class”,即使您從未真正聲明過“類”成員變量;編譯器使這一切都可以正常工作。 (此答案可能在 3 個月后對您不再有用,但以防萬一。)
答2:
huntsbot.com聚合了超過10+全球外包任務(wù)平臺的外包需求,尋找外包任務(wù)與機(jī)會變的簡單與高效。
如果文本與枚舉值不同的另一種解決方案:
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 是在這種情況下拋出異常的最佳實(shí)踐。 因?yàn)檫@是一種特殊情況。 “性能優(yōu)化”是編寫不可讀代碼的糟糕借口;-)
答3:
與HuntsBot一起,探索全球自由職業(yè)機(jī)會–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 中甚至更簡單,因?yàn)槟梢赃@樣做:Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity()))我還建議覆蓋 toString()(通過構(gòu)造函數(shù)傳入)并使用它而不是名稱,特別是如果 Enum 與可序列化數(shù)據(jù)相關(guān)聯(lián),因?yàn)檫@可以讓您控制套管沒有給聲納一個合適的。
Static initialization is inherently synchronized,因此絕對沒有理由在此處使用 ConcurrentHashMap,因?yàn)樵诔跏蓟蟮貓D永遠(yuǎn)不會被修改。因此,甚至例如 JLS 中的示例本身也使用常規(guī) HashMap。
答4:
與HuntsBot一起,探索全球自由職業(yè)機(jī)會–huntsbot.com
這是我使用的一個漂亮的實(shí)用程序:
/**
* 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;
}
然后在我的枚舉類中,我通常有這個來節(jié)省一些打字:
public static MyEnum fromString(String name) {
return getEnumFromString(MyEnum.class, name);
}
如果您的枚舉不是全部大寫,只需更改 Enum.valueOf 行。
太糟糕了,我不能將 T.class 用于 Enum.valueOf,因?yàn)?T 已被刪除。
那個空的 catch 塊真的讓我發(fā)瘋了,對不起。
@LazloBonin:異常是針對異常情況,而不是針對控制流。為自己獲取一份 Effective Java。
可怕!始終,始終捕獲可以處理的異常。上面的例子是一個如何不做的完美例子。為什么?所以它返回 NULL,然后調(diào)用者必須檢查 NULL 或拋出 NPE。如果調(diào)用者知道如何處理這種情況,那么執(zhí)行 if 與 try-catch 可能看起來更優(yōu)雅,但如果他無法處理,他必須再次傳遞 null 并且調(diào)用者的調(diào)用者必須再次檢查 NULL等等等等。
@whiskeysierra 我知道對 Java 或軟件開發(fā)充滿熱情是一回事,但你得冷靜一下。像這樣出人頭地/成為額外的人沒有任何好處。
返回 Optional 而不是 nullable 怎么樣?
答5:
huntsbot.com提供全網(wǎng)獨(dú)家一站式外包任務(wù)、遠(yuǎn)程工作、創(chuàng)意產(chǎn)品分享與訂閱服務(wù)!
你也應(yīng)該小心你的情況。讓我解釋一下:做 Blah.valueOf(“A”) 行,但 Blah.valueOf(“a”) 行不通。然后再次 Blah.valueOf(“a”.toUpperCase(Locale.ENGLISH)) 將工作。
在 Android 上,您應(yīng)該使用 Locale.US,作為 sulai points out。
請注意默認(rèn)語言環(huán)境!
答6:
保持自己快人一步,享受全網(wǎng)獨(dú)家提供的一站式外包任務(wù)、遠(yuǎn)程工作、創(chuàng)意產(chǎn)品訂閱服務(wù)–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(主要用于并發(fā))......這實(shí)際上不是使用它們的理由。它什么都不買 OP 并且性能更差......只需將所有項(xiàng)目的 for/next 循環(huán)替換為相同的 Stream 版本(甚至不是并行)。對于一些條目......誰在乎但要清楚,這不是一些“因?yàn)镴ava 8而更好”的例子。它只是返回 Optional vs null 的流利風(fēng)格的綠色與藍(lán)色“不同”實(shí)現(xiàn)(并且流利風(fēng)格需要所有連接方法的非空返回)。
答7:
huntsbot.com精選全球7大洲遠(yuǎn)程工作機(jī)會,涵蓋各領(lǐng)域,幫助想要遠(yuǎn)程工作的數(shù)字游民們能更精準(zhǔn)、更高效的找到對方。
這是一種可以對任何 Enum 執(zhí)行此操作的方法,并且不區(qū)分大小寫。
/**
* 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 是否真的是正確的合同。首先,查找失敗完全有可能(并且預(yù)期?)......它本身不在集合中(實(shí)際上是枚舉)。拋出 RuntimeException “在方法外傳播 [s]”。由于這不在方法簽名中 - 調(diào)用者不會期望它。最好使用 Map 構(gòu)造(在未找到時返回 null)或者甚至更好... Optional.empty()。
答8:
huntsbot.com匯聚了國內(nèi)外優(yōu)秀的初創(chuàng)產(chǎn)品創(chuàng)意,可按收入、分類等篩選,希望這些產(chǎn)品與實(shí)踐經(jīng)驗(yàn)?zāi)芙o您帶來靈感。
最好使用 Blah.valueOf(string),但您也可以使用 Enum.valueOf(Blah.class, string)。
答9:
huntsbot.com – 程序員副業(yè)首選,一站式外包任務(wù)、遠(yuǎn)程工作、創(chuàng)意產(chǎn)品分享訂閱平臺。
我的兩分錢:使用 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));
}
}
我將該函數(shù)重命名為 fromString(),因?yàn)槭褂迷摷s定命名它,您將從 Java 語言本身獲得一些好處;例如:
在 HeaderParam 注解處直接轉(zhuǎn)換類型
答10:
與HuntsBot一起,探索全球自由職業(yè)機(jī)會–huntsbot.com
如果您不想編寫自己的實(shí)用程序,請使用 Google 的 guava 庫:
Enums.getIfPresent(Blah.class, "A")
與內(nèi)置的 Java 函數(shù)不同,它讓您檢查 A 是否存在于 Blah 中并且不會引發(fā)異常。
答11:
huntsbot.com全球7大洲遠(yuǎn)程工作機(jī)會,探索不一樣的工作方式
您可能需要這樣做:
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文章來源:http://www.zghlxwxcb.cn/news/detail-563871.html
huntsbot.com高效搞錢,一站式跟進(jìn)超10+任務(wù)平臺外包需求文章來源地址http://www.zghlxwxcb.cn/news/detail-563871.html
到了這里,關(guān)于如何從Java中的字符串值中獲取枚舉值的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!