java स्ट्रिंग मान द्वारा लुकअप जावा एनम




enums (19)

Blah.valueOf(string) का उपयोग करना सबसे अच्छा है लेकिन आप Enum.valueOf(Blah.class, string) भी उपयोग कर सकते हैं।

कहो मेरे पास एक enum है जो बस है

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

और मैं एक स्ट्रिंग के enum मान को खोजना चाहता हूं, उदाहरण के लिए "A" जो Blah.A होगा। ऐसा करना कैसे संभव होगा?

Enum.valueOf() जिस विधि की मुझे आवश्यकता है? यदि हां, तो मैं इसका उपयोग कैसे करूं?


जावा 8 में स्थिर मानचित्र पैटर्न भी आसान है और मेरी पसंदीदा विधि है। यदि आप जैक्सन के साथ @JsonValue का उपयोग करना चाहते हैं तो आप @JsonValue को ओवरराइड कर सकते हैं और नाम के बजाए इसका उपयोग कर सकते हैं, फिर @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);
    }
}

यहां एक विधि है जो इसे किसी भी एनम के लिए कर सकती है, और मामला असंवेदनशील है।

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

Enum के निहित स्थिर विधि 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

प्रेरणा: जावा में एनम के 10 उदाहरण


java.lang.Enum कई उपयोगी विधियों को परिभाषित करता है, जो जावा में सभी गणना प्रकार के लिए उपलब्ध है:

  • आप किसी भी एनम स्थिरांक का नाम पाने के लिए name() विधि का उपयोग कर सकते हैं। स्ट्रिंग शाब्दिक एनम स्थिरांक लिखने के लिए प्रयोग किया जाता है उनका नाम है।
  • इसी प्रकार values() विधि का उपयोग एनम प्रकार से सभी एनम स्थिरांक की सरणी प्राप्त करने के लिए किया जा सकता है।
  • और पूछे जाने वाले प्रश्न के लिए, आप नीचे दिखाए गए अनुसार जावा में किसी भी स्ट्रिंग से एनम निरंतर रूपांतरित करने के लिए valueOf() विधि का उपयोग कर सकते हैं।
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() विधि एक एनम निरंतर लिंग देता है। मेल, उस रिटर्न पर नाम कॉल करना "MALE"


पिछले उत्तरों में जोड़ने के लिए, और नल और एनपीई के आसपास कुछ चर्चाओं को संबोधित करने के लिए मैं अनुपस्थित / अमान्य मामलों को संभालने के लिए गुवा विकल्प का उपयोग कर रहा हूं। यह यूआरआई / पैरामीटर पार्सिंग के लिए बहुत अच्छा काम करता है।

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

उन लोगों के लिए जिन्हें पता नहीं है, वैकल्पिक के साथ शून्य से बचने के बारे में कुछ और जानकारी यहां दी गई है: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional


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

सहायक उपयोगिता के साथ, शीर्ष रेटेड उत्तर में जोड़ना ...

valueOf() उन मामलों में दो अलग-अलग अपवाद फेंकता है जहां इसे इसके इनपुट पसंद नहीं हैं।

  • IllegalArgumentException
  • NullPointerExeption

यदि आपकी आवश्यकताएं ऐसी हैं कि आपके पास कोई गारंटी नहीं है कि आपकी स्ट्रिंग निश्चित रूप से एक enum मान से मेल खाती है, उदाहरण के लिए यदि स्ट्रिंग डेटा किसी डेटाबेस से आता है और इसमें enum का पुराना संस्करण हो सकता है, तो आपको इन्हें संभालना होगा अक्सर ...

तो यहां एक पुन: प्रयोज्य विधि है जिसे मैंने लिखा है जो हमें एक डिफ़ॉल्ट एनम को वापस करने की इजाजत देता है यदि हम जिस स्ट्रिंग को पास करते हैं वह मेल नहीं खाता है।

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
}

जावा 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 Blah fromText(String text) {
        return Arrays.stream(values())
          .filter(bl -> bl.text.equalsIgnoreCase(text))
          .findFirst()
          .orElse(null);
    }
}

व्हाट अबाउट?

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

मैं गणनाओं में तारों के रूप में कमांड को पार्स करने के लिए इस प्रकार की प्रक्रिया का उपयोग करना पसंद करता हूं। मेरे पास आमतौर पर "अज्ञात" के रूप में गणनाओं में से एक है, इसलिए यह उस लौटने में मदद करता है जब दूसरों को शून्य के बजाए (असंवेदनशील आधार पर भी) नहीं मिला (जिसका अर्थ है कि कोई मूल्य नहीं है)। इसलिए मैं इस दृष्टिकोण का उपयोग करता हूं।

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

आपको अपने मामले से भी सावधान रहना चाहिए। मुझे समझाएं: Blah.valueOf("A") काम करता है, लेकिन Blah.valueOf("a") काम नहीं करेगा। फिर फिर Blah.valueOf("a".toUpperCase(Locale.ENGLISH)) काम करेगा।

संपादित करें
टीसी पर आधारित toUpperCase(Locale.ENGLISH) बदल गया । टिप्पणी और जावा दस्तावेज़

Locale.US करें 2 एंड्रॉइड पर आपको Locale.US उपयोग करना चाहिए, जैसा कि सुलाई अंक बताते हैं


एक और समाधान अगर पाठ गणना मूल्य के समान नहीं है:

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

मेरे 2 सेंट यहाँ: जावा 8 स्ट्रीम का उपयोग कर + एक सटीक स्ट्रिंग की जांच:

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() से उस fromString() का उपयोग करके नामकरण करने के बाद नामित किया गया है, आपको जावा भाषा से कुछ लाभ प्राप्त होंगे; उदाहरण के लिए:

  1. हेडरपारा एनोटेशन में प्रकारों का प्रत्यक्ष रूपांतरण

अपाचे के commons-lang लाइब्रेरी में एक स्थिर फ़ंक्शन org.apache.commons.lang3.EnumUtils.getEnum जो आपके एनम प्रकार के स्ट्रिंग को मैप करेगा। जियोफ्रीज़ के रूप में अनिवार्य रूप से वही जवाब है, लेकिन जंगली में पहले से ही बाहर क्यों है।


आपको इसकी आवश्यकता हो सकती है:

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

और देखें:

उदाहरण के मानचित्र और मानचित्र का उपयोग करते हुए ओरेकल जावा उदाहरण

एनम प्रकार में स्थिर ब्लॉक के निष्पादन आदेश

मैं अपने स्ट्रिंग मान से जावा एनम कैसे देख सकता हूं


हे (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;
        }

}

विपरीत तरीके से कैप्चरिंग एक और उपयोगिता। उस मान का उपयोग करना जो एनम की पहचान करता है, न कि उसके नाम से।

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 देता है, क्योंकि यह "drei" से मेल खाने के लिए Foo.THREE का उपयोग करेगा, जो अनूठा सार्वजनिक है, अंतिम नहीं है और Foo में स्थिर विधि नहीं है। यदि फू सार्वजनिक रूप से अधिक है, अंतिम और स्थैतिक विधि नहीं है, उदाहरण के लिए, getTranslate जो "drei" देता है, अन्य विधि का उपयोग किया जा सकता है: EnumUtil.from(Foo.class, "drei", "getTranslate")





enums