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



enum swift (16)

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

}

https://code.i-harness.com

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

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

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

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


أحب استخدام هذا النوع من العمليات لتحليل الأوامر كسلسلة في التعدادات. عادةً ما يكون لدي أحد التعدادات كـ "غير معروف" ، لذا فإنه يساعد على إرجاع ذلك عندما لا يتم العثور على الآخرين (حتى على أساس حالة غير حساس) بدلاً من أن تكون خالية (أي أنه لا توجد قيمة). ومن ثم استخدم هذا النهج.

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

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

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
}

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


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

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


سنتي 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

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


في Java 8 ، يكون نمط الخريطة الثابتة أكثر سهولة وهو الطريقة المفضلة. إذا كنت تريد استخدام Enum with 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);
    }
}

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

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


ماذا عن؟

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

وإليك هذه الطريقة التي يمكن أن تفعل ذلك لأي تعداد ، وغير حساس لحالة الأحرف.

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

وهنا فائدة أنيق يمكنني استخدامها:

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

إذا لم يكن كل التعدادات الخاصة بك عبارة عن أحرف استهلالية ، Enum.valueOf سوى تغيير السطر Enum.valueOf .

سيئة للغاية لا أستطيع استخدام T.class لـ Enum.valueOf كما تم مسح T


يعرّف 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" .


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




enums