ว่าฉันมี enum ซึ่งเป็นเพียงแค่
public enum Blah {
A, B, C, D
}
และผมอยากจะหาค่า enum ของสตริง, ตัวอย่างซึ่งจะเป็น"A"
Blah.A
เป็นไปได้อย่างไรที่จะทำเช่นนี้?
เป็นEnum.valueOf()
วิธีที่ฉันต้องการหรือไม่ ถ้าเป็นเช่นนั้นฉันจะใช้มันได้อย่างไร
ว่าฉันมี enum ซึ่งเป็นเพียงแค่
public enum Blah {
A, B, C, D
}
และผมอยากจะหาค่า enum ของสตริง, ตัวอย่างซึ่งจะเป็น"A"
Blah.A
เป็นไปได้อย่างไรที่จะทำเช่นนี้?
เป็นEnum.valueOf()
วิธีที่ฉันต้องการหรือไม่ ถ้าเป็นเช่นนั้นฉันจะใช้มันได้อย่างไร
คำตอบ:
ใช่จะทำให้คุณBlah.valueOf("A")
Blah.A
โปรดทราบว่าชื่อจะต้องเป็นที่แน่นอนการแข่งขันรวมทั้งกรณี: Blah.valueOf("a")
และทั้งโยนBlah.valueOf("A ")
IllegalArgumentException
วิธีการคงที่valueOf()
และvalues()
ถูกสร้างขึ้นในเวลารวบรวมและไม่ปรากฏในซอร์สโค้ด พวกเขาปรากฏใน Javadoc แม้ว่า; ตัวอย่างเช่นDialog.ModalityType
แสดงทั้งสองวิธี
toString()
คุณค่าไม่ใช่ฉันจะไม่พูดอย่างนั้น name()
คุณจะได้รับชื่อที่กำหนดจริงของค่าคงที่ enum เว้นแต่คุณจะแทนที่
enum Blah {...}
ความหมายไม่ควรพยายามที่จะประกาศตัวของมันเองมิได้values
valuesOf
มันเหมือนกับวิธีที่คุณสามารถเขียน "AnyTypeName.class" แม้ว่าคุณจะไม่เคยประกาศตัวแปรสมาชิก "class" คอมไพเลอร์ทำให้มันใช้งานได้ทั้งหมด (คำตอบนี้อาจไม่เป็นประโยชน์กับคุณ 3 เดือนต่อมา แต่เพียงในกรณีที่.)
วิธีแก้ไขอื่นหากข้อความไม่เหมือนกับค่าการแจงนับ:
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
จะดีกว่า
นี่คือยูทิลิตี้ที่ดีที่ฉันใช้:
/**
* 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);
}
หาก enums ของคุณไม่ใช่ตัวพิมพ์ใหญ่ทั้งหมดเพียงแค่เปลี่ยนEnum.valueOf
บรรทัด
ผมเสียดายที่ไม่สามารถใช้T.class
สำหรับEnum.valueOf
เป็นT
จะถูกลบทิ้ง
ใช้รูปแบบจาก Joshua Bloch, 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(),instance);
}
ENUM_MAP = Collections.unmodifiableMap(map);
}
public static MyEnum get (String name) {
return ENUM_MAP.get(name);
}
}
ดูเพิ่มเติมที่:
ตัวอย่าง Oracle Java ที่ใช้ Enum และ Map ของอินสแตนซ์
Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity()))
ฉันยังแนะนำให้ใช้ toString () (ส่งผ่านผ่าน Constructor) และใช้ชื่อนั้นแทนชื่อโดยเฉพาะถ้า Enum เชื่อมโยงกับข้อมูลที่สามารถทำให้เป็นอนุกรมได้ โซนาร์แบบพอดี
unmodifiableMap
ใช้เพียงConcurrentHashMap
HashMap
(ถ้าคุณมี Guava ImmutableMap
แล้วฉันขอแนะนำให้แทน!)
ConcurrentHashMap
ที่นี่ที่ซึ่งแผนที่ไม่เคยถูกแก้ไขหลังจากการเริ่มต้น ดังนั้นทำไมแม้เช่นตัวอย่างใน JLS HashMap
ที่ตัวเองใช้เป็นประจำ
คุณควรระมัดระวังกรณีของคุณ ให้ฉันอธิบาย: Blah.valueOf("A")
ทำงาน แต่Blah.valueOf("a")
จะไม่ทำงาน จากนั้นBlah.valueOf("a".toUpperCase(Locale.ENGLISH))
ก็จะทำงานอีกครั้ง
แก้ไข
เปลี่ยนtoUpperCase
เป็นtoUpperCase(Locale.ENGLISH)
อ้างอิงจากtc ความคิดเห็นและเอกสาร java
Locale.US
อินพุต / เอาต์พุตของเครื่องที่สามารถอ่านได้อย่างชัดเจน
นี่คือวิธีการที่สามารถทำได้สำหรับ 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()
));
}
equalsIgnoreCase
เป็นวิธีที่จะไป +1
การใช้Blah.valueOf(string)
ดีที่สุด แต่คุณก็สามารถใช้ได้Enum.valueOf(Blah.class, string)
เช่นกัน
ใน 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();
}
}
หากคุณไม่ต้องการเขียนโปรแกรมอรรถประโยชน์ของคุณเองให้ใช้ Google ฝรั่ง ห้องสมุด:
Enums.getIfPresent(Blah.class, "A")
ซึ่งแตกต่างจากฟังก์ชั่นจาวาในตัวมันช่วยให้คุณตรวจสอบว่า A มีอยู่ใน Blah และไม่ส่งข้อยกเว้น
2 เซนต์ของฉันที่นี่: ใช้ Java8 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()
ตั้งแต่ตั้งชื่อโดยใช้การประชุมนั้นคุณจะได้รับประโยชน์จากภาษาจาวาเอง ตัวอย่างเช่น:
switch
บล็อกที่อ่านได้มากขึ้นคุณสามารถ.orElse(null)
แทน.orElseThrow()
เพื่อให้คุณสามารถเขียนรหัสข้อยกเว้นในdefault
ประโยค - และรวมถึงข้อมูลที่เป็นประโยชน์มากขึ้นเมื่อจำเป็น และเพื่อให้ผ่อนปรนมากขึ้นคุณสามารถใช้v -> Objects.equals(v.name, s == null ? "" : s.trim().toUpperCase())
Optional
จากการfindFirst()
ช่วยให้ผู้ใช้ในการตัดสินใจว่าเขาต้องการ.orElse(null)
, orElseThrow()
หรืออะไรก็ตาม ....
คุณอาจต้อง:
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 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;
}
สิ่งนี้จะคืนค่าให้คุณโดยชื่อ Enum ที่ถูกทำให้เป็นสตริงสำหรับเช่นถ้าคุณให้ "PERSON" ใน fromEnumName มันจะส่งคืนค่า Enum เช่น "บุคคล"
อีกวิธีหนึ่งในการทำเช่นนี้โดยใช้วิธีคงที่โดยนัยname()
ของ Enum ชื่อจะส่งกลับสตริงที่แน่นอนที่ใช้ในการสร้าง enum ที่สามารถใช้ในการตรวจสอบกับสตริงที่ระบุ:
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
Inspiration: 10 ตัวอย่าง Enum ใน Java
valueOf
คุณต้องการ วิธีการแบบคงที่นี้ไม่ได้ให้อะไรพิเศษยกเว้นและทั้งหมด ดังนั้นโครงสร้าง if / else จะมีอันตรายมาก ... ค่าคงที่ enum ใหม่ใด ๆ ที่เพิ่มเข้ามาจะทำให้วิธีการนี้พังโดยไม่มีการเปลี่ยนแปลง
name()
ไม่คงที่
วิธีการแก้ปัญหาโดยใช้ห้องสมุด 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();
}
}
เพื่อเพิ่มคำตอบก่อนหน้านี้และพูดถึงการอภิปรายบางส่วนเกี่ยวกับค่า 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();
}
}
}
สำหรับผู้ที่ไม่ทราบต่อไปนี้เป็นข้อมูลเพิ่มเติมเกี่ยวกับการหลีกเลี่ยงค่า null ด้วยตัวเลือก: https://code.google.com/p/guava-l ไลบรารี/wiki/UsingAndAvoidingNullExplained #Optional
ใน Java 8 รูปแบบแผนที่แบบคงที่นั้นง่ายยิ่งขึ้นและเป็นวิธีที่ฉันไว้ล่วงหน้า หากคุณต้องการใช้ Enum กับ Jackson คุณสามารถแทนที่ 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);
}
}
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;
}
วิธี O (1) เป็นแรงบันดาลใจจากรหัสที่สร้างขึ้นอย่างรวดเร็วซึ่งใช้ hashmap
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;
}
}
Enum มีประโยชน์มากฉันใช้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");
เกี่ยวกับอะไร
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();
}
}
}
java.lang.Enum
กำหนดวิธีการที่มีประโยชน์หลายวิธีซึ่งมีอยู่ในประเภทการแจงนับทั้งหมดใน Java:
name()
วิธีการรับชื่อค่าคง Enum ใด ๆ สตริงตัวอักษรที่ใช้ในการเขียนค่าคง Enum เป็นชื่อของพวกเขาvalues()
วิธีการในทำนองเดียวกันสามารถใช้ในการรับอาร์เรย์ของค่าคงที่ Enum ทั้งหมดจากประเภท EnumvalueOf()
วิธีการแปลงค่าคงที่ String เป็น Enum ใน Java ดังที่แสดงด้านล่าง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"
เรียกชื่อในผลตอบแทนที่
ไลบรารีcommons-langของ Apache มีฟังก์ชั่นคงที่org.apache.commons.lang3.EnumUtils.getEnumซึ่งจะแมปสตริงกับประเภท Enum ของคุณ คำตอบเดียวกับ Geoffreys แต่ทำไมคุณต้องม้วนตัวเองเมื่อมันอยู่ในป่าแล้ว
การเพิ่มคำตอบให้คะแนนสูงสุดด้วยประโยชน์ที่เป็นประโยชน์ ...
valueOf()
โยนข้อยกเว้นที่แตกต่างกันสองกรณีในกรณีที่ไม่ชอบอินพุต
IllegalArgumentException
NullPointerExeption
หากความต้องการของคุณเป็นเช่นนั้นคุณไม่มีการรับประกันว่า String ของคุณจะจับคู่ค่า enum อย่างแน่นอนตัวอย่างเช่นถ้าข้อมูล String มาจากฐานข้อมูลและอาจมี enum เวอร์ชันเก่าคุณจะต้องจัดการสิ่งเหล่านี้ บ่อยครั้ง...
ดังนั้นนี่เป็นวิธีที่นำกลับมาใช้ใหม่ได้ฉันเขียนซึ่งช่วยให้เรากำหนด 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.THINGTWO
valueOf("THINGZERO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGONE
}
ในฐานะที่เป็นswitch
รุ่นที่ยังไม่ได้รับการกล่าวถึงยังฉันแนะนำมัน (reum OP ของ enum):
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)
โดยไม่ต้องขว้างปาIllegalArgumentException
ในลักษณะที่ว่าในกรณีใด ๆnull
จะถูกส่งกลับ ดังนั้นเราจึงโยนNullPointerException
ถ้ามีชื่อเป็นnull
และในกรณีของdefault
ถ้าเป็นdefaultValue
null
นั่นเป็นวิธีการvalueOfOrDefault
ทำงาน
วิธีนี้ใช้การออกแบบMap
-Interface ซึ่งมีวิธีการMap.getOrDefault(Object key, V defaultValue)
เป็นของ Java 8
ยูทิลิตี้อื่นที่จับภาพในทางกลับกัน ใช้ค่าที่ระบุว่า 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
ที่ผลตอบแทน "drei" วิธีการอื่น ๆ EnumUtil.from(Foo.class, "drei", "getTranslate")
ที่สามารถนำมาใช้:
valueOf<MyEnum>("value")
สร้างส่วนขยายแล้วโทร หากประเภทไม่ถูกต้องคุณจะได้รับโมฆะและต้องจัดการ
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)
และการหลีกเลี่ยงการตอบกลับที่ไม่เป็นผล คุณสามารถขยาย enum เฉพาะของคุณเพื่อให้ค่าเริ่มต้นเป็นแบบอัตโนมัติ
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
ฉันชอบที่จะใช้กระบวนการประเภทนี้เพื่อแยกคำสั่งเป็นสตริงในการแจกแจง ปกติแล้วฉันจะมีหนึ่งในการแจกแจงว่า "ไม่ทราบ" ดังนั้นจึงช่วยให้มีการส่งคืนเมื่อไม่พบผู้อื่น (แม้ในกรณีที่ไม่มีความรู้สึกพื้นฐาน) แทนที่จะเป็นโมฆะ (หมายถึงไม่มีค่า) ดังนั้นฉันใช้วิธีนี้
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;
}
วิธีที่เร็วที่สุดในการรับชื่อ enum คือการสร้างแผนที่ของข้อความและค่า enum เมื่อเริ่มต้นแอปพลิเคชันและรับชื่อเรียกใช้ฟังก์ชัน 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());
}
}
Blah.valueOf("A")
วิธีการนี้ต้องคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่และไม่ทนต่อช่องว่างภายนอกดังนั้นทางเลือกอื่นที่เสนอโดย @ JoséMi