java شرح - بحث التعداد جاوة حسب قيمة السلسلة




enum in (20)

ماذا عن؟

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

قل لدي تعداد فقط

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

وأود أن العثور على قيمة التعداد لسلسلة ، على سبيل المثال "A" التي ستكون Blah.A كيف سيكون من الممكن القيام بذلك؟

هل Enum.valueOf() الطريقة التي Enum.valueOf() ؟ إذا كان الأمر كذلك ، كيف أستخدم هذا؟


للإضافة إلى الإجابات السابقة ، ومعالجة بعض المناقشات حول القيم الخالية و 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-libraries/wiki/UsingAndAvoidingNullExplained#Optional


الحل باستخدام مكتبات الجوافة. يكون أسلوب 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();
   }
}

استخدم النمط من Joshua Bloch، Effective 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);
  }
}

انظر أيضا:

أوراكل جافا مثال باستخدام التعداد وخريطة الحالات

ترتيب تنفيذ الكتل الثابتة في نوع التعداد

كيف يمكنني البحث عن تعداد Java من قيمة String الخاصة به


يعرّف java.lang.Enum عدة طرق مفيدة ، وهي متاحة لجميع أنواع التعداد في جافا:

  • يمكنك استخدام الأسلوب name() للحصول على اسم أي ثوابت التعداد. سلسلة حرفية تستخدم لكتابة ثواب التعداد هو اسمها.
  • وبالمثل ، يمكن استخدام values() الطريقة للحصول على صفيف لجميع ثوابت التعداد من نوع التعداد.
  • وبالنسبة للسؤال المطروح ، يمكنك استخدام أسلوب valueOf() لتحويل أي من 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" .


طريقة أخرى للقيام بذلك عن طريق استخدام name() الأسلوب الضمني الثابت 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 أمثلة من التعداد في جاوة


حل آخر إذا لم يكن النص هو نفسه لقيمة التعداد:

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

تحتوي مكتبة commons-lang في Apache على وظيفة ثابتة org.apache.commons.lang3.EnumUtils.getEnum والتي ستقوم بتعيين سلسلة إلى نوع التعداد الخاص بك. نفس الجواب جوهريا مثل جيفريز ولكن لماذا تتدحرج عندما يكون هناك في البرية بالفعل.


إذا كنت لا ترغب في كتابة فائدتك الخاصة استخدم مكتبة guava من Google:

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

على عكس ما تم بناؤه في وظيفة java ، فإنه يتيح لك التحقق مما إذا كان A موجودًا في Blah ولا يلقي استثناءً.


قد تحتاج إلى هذا:

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

هذا سيعرض لك القيمة بواسطة اسم التعداد Stringified على سبيل المثال إذا قمت بتوفير "PERSON" في fromEnumName فسوف يعطيك قيمة Enum أي "Person"


استخدام Blah.valueOf(string) هو الأفضل ولكن يمكنك استخدام Enum.valueOf(Blah.class, string) أيضاً.


نعم ، Blah.valueOf("A") سوف يعطيك Blah.A

لاحظ أن الاسم يجب أن يكون مطابقًا Blah.valueOf("a") ، بما في ذلك الحالة: Blah.valueOf("a") و Blah.valueOf("A ") كلاهما يرمي IllegalArgumentException .

يتم إنشاء values() الثابتة valueOf() values() في وقت التحويل البرمجي ولا تظهر في التعليمات البرمجية المصدر. تظهر في Javadoc ، رغم ذلك ؛ على سبيل المثال ، يعرض Dialog.ModalityType كلا الطريقتين.


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

إضافة إلى الإجابة الأعلى تقييمًا ، مع فائدة مفيدة ...

valueOf() استثناءين مختلفين في الحالات التي لا يحب فيها الإدخال.

  • IllegalArgumentException
  • NullPointerExeption

إذا كانت متطلباتك لا تضمن لك بالضرورة أن تطابق سلسلتك قيمة التعداد ، على سبيل المثال إذا كانت بيانات السلسلة تأتي من قاعدة بيانات ويمكن أن تحتوي على نسخة قديمة من التعداد ، فستحتاج إلى التعامل مع هذه في كثير من الأحيان ...

إذن هذه طريقة قابلة لإعادة الاستخدام كتبتها والتي تسمح لنا بتعريف 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
}

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

سنتي 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() منذ تسميتها باستخدام هذه الاتفاقية ، ستحصل على بعض الفوائد من لغة Java نفسها ؛ فمثلا:

  1. التحويل المباشر للأنواع عند التعليق التوضيحي HeaderParam

يجب عليك أيضا أن تكون حذرا مع قضيتك. اسمحوا لي أن أشرح: القيام يعمل Blah.valueOf("A") ، ولكن Blah.valueOf("a") يعمل Blah.valueOf("a") . ثم مرة أخرى Blah.valueOf("a".toUpperCase(Locale.ENGLISH)) ستعمل.

تصحيح
تم تغيير toUpperCase إلى toUpperCase(Locale.ENGLISH) استنادًا إلى tc. تعليق و java docs

edit2 على الروبوت يجب عليك استخدام Locale.US ، كما يشير sulai .


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

}

فائدة أخرى تلتقط في الاتجاه المعاكس. باستخدام قيمة تحدد هذا التعداد ، وليس من اسمه.

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. في حالة أن Foo لديه أكثر من عام وليس نهائياً ولا طريقة ثابتة ، على سبيل المثال getTranslate التي ترجع "drei" ، يمكن استخدام الطريقة الأخرى: EnumUtil.from(Foo.class, "drei", "getTranslate") .


أنا مندهش بعض الشيء أن لا أحد ذكرنا منشئ Integer الذي يأخذ String كمعلمة.
إذن ، ها هو:

String myString = "1234";
int i1 = new Integer(myString);

جافا 8 - عدد صحيح (سلسلة) .

وبطبيعة الحال ، سيقوم المُنشئ بإرجاع Type Integer ، وتقوم عملية unboxing بتحويل القيمة إلى int .

من المهم أن أذكر
يستدعي هذا المنشئ أسلوب parseInt .

public Integer(String var1) throws NumberFormatException {
    this.value = parseInt(var1, 10);
}






java enums