java কিভাবে জাভা একটি স্ট্রিং মান থেকে একটি enum মান পেতে?




enums (20)

বলুন আমি একটি enum আছে যা শুধু

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

এবং আমি একটি স্ট্রিং এর enum মান খুঁজে পেতে চাই, উদাহরণস্বরূপ "A" যা Blah.A । এটা কিভাবে করা সম্ভব হবে?

Enum.valueOf() পদ্ধতিটি কি আমার প্রয়োজন? যদি তাই হয়, আমি কিভাবে এই ব্যবহার করব?


Blah.valueOf(string) ব্যবহার করা ভাল তবে আপনি Enum.valueOf(Blah.class, string) ব্যবহার করতে পারেন।


Apache এর commons-lang লাইব্রেরিতে একটি static function org.apache.commons.lang3.EnumUtils.getEnum যা আপনার Enum টাইপের স্ট্রিং ম্যাপ করবে। জ্যোফ্রেইসের মতোই একই উত্তর কিন্তু কেন বুনো ইতিমধ্যে সেখানে আপনার নিজের রোল কেন।


পূর্ববর্তী উত্তরগুলিতে যোগ করার জন্য, এবং নুলস এবং এনপিইর চারপাশে কিছু আলোচনায় ঠিকানা লিখুন আমি অনুপস্থিত / অবৈধ ক্ষেত্রে পরিচালনা করার জন্য গুওয়া বিকল্পগুলি ব্যবহার করছি। এই 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();
        }
    }
}

যারা সচেতন নয়, এখানে ঐচ্ছিক সঙ্গে অস্পষ্ট এড়াতে আরও কিছু তথ্য এখানে রয়েছে: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional


আপনি আপনার ক্ষেত্রে সতর্কতা অবলম্বন করা উচিত। আমাকে ব্যাখ্যা করুন: Blah.valueOf("A") কাজ করে, কিন্তু Blah.valueOf("a") কাজ করবে না। তারপর আবার Blah.valueOf("a".toUpperCase(Locale.ENGLISH)) কাজ করবে।

সম্পাদন করা
TC উপর ভিত্তি করে toUpperCase(Locale.ENGLISH) toUpperCase টু toUpperCase(Locale.ENGLISH) তে পরিবর্তন হয়েছে । মন্তব্য এবং জাভা ডক্স

সম্পাদনা 2 এন্ড্রয়েড আপনাকে Locale.US ব্যবহার করতে হবে। Locale.US , সুুলাই পয়েন্ট হিসাবে।


হে (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;
        }

}

শীর্ষ সাহায্য উত্তর যোগ করা, একটি সহায়ক ইউটিলিটি সঙ্গে ...

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
}

গুওয়া লাইব্রেরি ব্যবহার করে সমাধান। পদ্ধতি GetPlanet () ক্ষেত্রে অসংবেদক, তাই GetPlanet ("Mercury") প্ল্যানেট ফিরে আসবে। 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();
   }
}

আমার 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() থেকে কনভেনশন ব্যবহার করে এটি পুনরায় নামকরণ করা হয়েছে, আপনি জাভা ভাষা থেকে নিজের কিছু সুবিধা পাবেন; উদাহরণ স্বরূপ:

  1. হেডারপারাম টীকাতে টাইপের সরাসরি রূপান্তর

বিপরীত পথে আরেকটি ইউটিলিটি ক্যাপচার। একটি মান ব্যবহার করে যা 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 ফিরিয়ে Foo.THREE , কারণ এটি " getValue " এর সাথে getValue পেতে getValue ব্যবহার করবে, যা অনন্য জনসাধারণ, চূড়ান্ত নয় এবং Foo তে স্ট্যাটিক পদ্ধতি নয়। যদি Foo জনসাধারণের চেয়ে বেশি থাকে তবে চূড়ান্ত নয় এবং স্থির পদ্ধতি নয়, উদাহরণস্বরূপ, getTranslate যা "drei" প্রদান করে, অন্য পদ্ধতিটি ব্যবহার করা যেতে পারে: EnumUtil.from(Foo.class, "drei", "getTranslate")


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

হ্যাঁ, Blah.valueOf("A") আপনাকে Blah.A দিতে হবে।

উল্লেখ্য যে নামটি অবশ্যই একটি সঠিক মিল হওয়া উচিত, যার মধ্যে রয়েছে: Blah.valueOf("a") এবং Blah.valueOf("A ") উভয় একটি IllegalArgumentException নিক্ষেপ করে।

স্ট্যাটিক পদ্ধতি values() valueOf() এবং values() কম্পাইল সময় তৈরি করা হয় এবং সোর্স কোডে উপস্থিত হয় না। তারা জাভাডোকে উপস্থিত থাকলেও; উদাহরণস্বরূপ, Dialog.ModalityType উভয় পদ্ধতি দেখায়।


কার্যকর জাভা জোশুয়া ব্লোকের প্যাটার্নটি ব্যবহার করুন:

(সংক্ষিপ্তত্ব জন্য সরলীকৃত)

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

এছাড়াও দেখুন:

উদাহরণস্বরূপ Enum এবং মানচিত্র ব্যবহার করে Oracle জাভা উদাহরণ

Enum টাইপ স্ট্যাটিক ব্লক এক্সিকিউশন অর্ডার

আমি কিভাবে তার স্ট্রিং মান থেকে একটি জাভা enum সন্ধান করতে পারেন


একটি switch বর্ধন হিসাবে এখনো উল্লেখ করা হয় নি আমি এটি পরিচয় করিয়ে দিচ্ছি (ওপি এর 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;
      }
    }
  }

একটি ডিফল্ট মান প্রদান করে আমরা একটি IllegalArgumentException নিক্ষেপ না করেই Enum.valueOf(String name) IllegalArgumentException যাতে কোন ক্ষেত্রে null ফিরে আসে। অতএব আমরা যদি NullPointerException নিক্ষেপ NullPointerException তবে নামটি NullPointerException এবং যদি default defaultValue null হয় তবে default ক্ষেত্রে। যে কিভাবে valueOfOrDefault কাজ করে।

এই পদ্ধতিটি Map ইন্টারফেসের নকশা গ্রহণ করে যা জাভা 8 এর মতো একটি পদ্ধতি Map.getOrDefault(Object key, V defaultValue)


আপনি যদি নিজের ইউটিলিটি লিখতে না চান তবে Google এর guava লাইব্রেরি ব্যবহার করুন:

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

জাভা ফাংশনে নির্মিত এটির বিপরীতে এটি আপনাকে পরীক্ষা করে দেখায় যে এটি A ব্লা এ উপস্থিত রয়েছে কিনা এবং ব্যতিক্রমটি নিক্ষেপ করে না।


কি সম্পর্কে?

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

আপনি এই প্রয়োজন হতে পারে:

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 নাম দ্বারা মানটি ফেরত দেবে যেমন, যদি আপনি EnumName থেকে "PERSON" সরবরাহ করেন তবে এটি আপনাকে 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()
    ));
}

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

অনুপ্রেরণা: জাভা Enum এর 10 উদাহরণ


java.lang.Enum বিভিন্ন কার্যকর পদ্ধতি সংজ্ঞায়িত করে, যা জাভাতে সমস্ত গণনার java.lang.Enum উপলব্ধ:

  • আপনি Enum Constants এর নাম পেতে name() পদ্ধতি ব্যবহার করতে পারেন। স্ট্রিং আক্ষরিক লিখুন Enum constants লিখুন তাদের নাম।
  • একইভাবে values() পদ্ধতিটি Enum টাইপ থেকে সমস্ত এননাম স্টোনগুলির একটি অ্যারে পেতে ব্যবহার করা যেতে পারে।
  • এবং জিজ্ঞাসিত প্রশ্নাবলীর জন্য, আপনি valueOf() যেকোনো স্ট্রিং এ Enum ধ্রুবক রূপান্তর করতে 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() পদ্ধতি একটি Enum ধ্রুবক লিঙ্গ। Return করে, যে ফেরত নাম কলিং "MALE"





enums