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


1982

বলুন আমার কাছে এমন একটি এনাম রয়েছে যা ন্যায্য

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

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

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

উত্তর:


2258

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

নোট করুন যে নামটি অবশ্যই কেস সহ একটি যথাযথ মিল হতে পারে : Blah.valueOf("a")এবং Blah.valueOf("A ")উভয়ই একটি নিক্ষেপ করে IllegalArgumentException

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


100
রেফারেন্সের জন্য, Blah.valueOf("A")পদ্ধতিটি কেস সংবেদনশীল এবং বহিরাগত সাদা স্থান সহ্য করে না, এইভাবে @ জোসমি'র নীচে প্রস্তাবিত বিকল্প সমাধান al
ব্রেট

3
@ মিশেল মাইয়ার্স, যেহেতু এই উত্তরটি এখন পর্যন্ত সবচেয়ে বেশি ভোট দেওয়া হয়েছে, তাই আমি কি বুঝতে পারি যে এনাম এবং তার স্ট্রিংয়ের মানটি হুবহু এক হিসাবে সংজ্ঞায়িত করা ভাল অনুশীলন?
কেভিন মেরেডিথ

4
@ কেভিনমারেদিথ: আপনি যদি toString()মানটি বোঝাতে চান , না, আমি এটি বলব না। name()আপনি এনাম ধ্রুবকের প্রকৃত সংজ্ঞায়িত নামটি পাবেন যদি না আপনি এটিকে ওভাররাইড করে।
মাইকেল ময়র্স

3
"সংকলন সময়ে তৈরি করা হয়েছে এবং উত্স কোডে উপস্থিত হয় না" বলতে আপনি ঠিক কী বোঝাতে চাইছেন। ?
গাছগুলিআর সর্বত্র কোথাও

8
@ ট্রিআরিএইরিওর কোথাও আরও নির্দিষ্টভাবে, এই পদ্ধতিগুলি সংকলক দ্বারা তৈরি করা হয় (বা সংশ্লেষিত )। প্রকৃত enum Blah {...}সংজ্ঞা নিজস্ব ডিক্লেয়ার করার চেষ্টা করা উচিত নয় valuesকিংবা valuesOf। এটি এমন কী আপনি কীভাবে "যে কোনও টাইপনাম.ক্লাস" লিখতে পারেন তা সত্ত্বেও আপনি বাস্তবে কোনও "শ্রেণি" সদস্যের পরিবর্তনশীল ঘোষণা করেননি; সংকলক এটি সব ঠিক কাজ করে তোলে। (এই উত্তরটি 3 মাস পরে আপনার পক্ষে আর কার্যকর নাও হতে পারে তবে কেবল ক্ষেত্রে))
ত্রি স্টারগা

864

আর একটি সমাধান যদি পাঠ্যটি গণনা মানের মতো হয় না:

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

396
throw new IllegalArgumentException("No constant with text " + text + " found")চেয়ে ভাল হবে return null
হুইস্কিসিয়ার

8
@ হুইস্কিসিয়ার জোন স্কিট তাতে একমত হবে না। stackoverflow.com/questions/1167982/...
Sanghyun লি

11
@ সাংডল আপনি কি আমাদের আলোকিত করতে পারেন কেন নাল ফেরানো ভাল?
হুইস্কিসিয়ার

57
@ সাঙ্গদল সাধারণত সান - ওফ - ওরাকল একই পরিস্থিতিতে কী করছে তা যাচাই করা ভাল জিনিস। এবং হিসাবে Enum.valueOf () দেখানো হয় এটা IS সেরা অনুশীলনের এই ক্ষেত্রে একটি ব্যতিক্রম নিক্ষেপ করা। কারণ এটি একটি ব্যতিক্রমী পরিস্থিতি। "পারফরম্যান্স অপটিমাইজেশন"
অপঠনযোগ্য

5
ঠিক আছে, আপনি এটি "পাঠযোগ্য" ;
@

121

এখানে আমি ব্যবহার করছি একটি নিফটি ইউটিলিটি:

/**
 * 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লাইনটি পরিবর্তন করুন ।

এটা খুব খারাপ, আমি ব্যবহার করতে পারবেন না T.classজন্য Enum.valueOfযেমন Tমুছে ফেলা হয়।


176
এই খালি ক্যাচ ব্লকটি আমাকে সত্যিই বাদামের দিকে চালিত করে, দুঃখিত।
হুইস্কিসিয়ার

32
@ লেজলোবিনিন: ব্যতিক্রমগুলি ব্যতিক্রমী অবস্থার জন্য, নিয়ন্ত্রণ প্রবাহের জন্য নয়। কার্যকর জাভার একটি অনুলিপি নিজেকে পান ।
মনিকা পুনরায় ইনস্টল করুন - এম। শ্র্রেডার

10
আপনি যদি জাভা এপিআই ব্যবহার করতে চান তবে একটি ব্যতিক্রম ছুঁড়ে ফেলতে চান এবং আপনি আপনার কোডটি একটি নিক্ষেপ করতে চান না, আপনি হয় তবে এটির মতো ব্যতিক্রমটিকে গ্রাস করতে পারেন, বা স্ক্র্যাচ থেকে যুক্তিটি আবার লিখতে পারেন যাতে কোনও ব্যতিক্রম প্রথম স্থানে ফেলে দেওয়া হয় না। ব্যতিক্রম গিলে ফেলা প্রায়শই কম খারাপ হয়।
নেট সি কে

47
ভয়ঙ্কর! সর্বদা, সর্বদা ব্যতিক্রমগুলি ধরুন যেখানে আপনি সেগুলি পরিচালনা করতে পারেন। উপরের উদাহরণটি কীভাবে এটি করবেন না তার একটি নিখুঁত উদাহরণ । কেন? সুতরাং এটি NULL ফেরত দেয়, এবং ফোনকারীকে তারপরে NULL এর বিরুদ্ধে পরীক্ষা করতে হয় বা একটি এনপিই নিক্ষেপ করতে হয়। আহ্বানকারী জানে নাকি পরিস্থিতি সামাল দিতে তারপর যদি বনাম চেষ্টা-ধরা করছেন একটি বিট আরো মার্জিত মনে হতে পারে, কিন্তু সে যদি হ্যান্ডেল করতে পারে না তিনি নাল আবার পাস এবং আহ্বায়ক আহ্বানকারী আবার শূন্য বিরুদ্ধে চেক করতে হয়েছে ইত্যাদি ইত্যাদি
রৌডি

10
উপরের সমাধানটি ন্যায়সঙ্গত হওয়ার জন্য, এমন কিছু ঘটনা রয়েছে যা আপনাকে অবৈধ অরগিউমেন্টএক্সেপশনটি ছুঁড়ে ফেলার পরিবর্তে নালায় ফিরে আসতে হবে এবং আপনার প্রোগ্রামের প্রবাহকে সরিয়ে ফেলবে, উদাহরণস্বরূপ, ওয়েব সার্ভিস স্কিমা এবং একটি ডেটাবেস স্কিমার মধ্যে এনামগুলিকে ম্যাপিং করা যেখানে তারা সবসময় এক নয় are -একজনের প্রতি. তবে, আমি একমত যে ক্যাচ ব্লকটি কখনই খালি রাখা উচিত নয়। লগ.ওয়ার্নের মতো ট্র্যাকিংয়ের উদ্দেশ্যে কিছু কোড রাখুন।
অ্যাড্রিয়ান এম

101

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

(বংশবৃদ্ধির জন্য সরলীকৃত)

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

আরও দেখুন:

এনাম এবং দৃষ্টান্তের মানচিত্র ব্যবহার করে ওরাকল জাভা উদাহরণ

একটি এনাম ধরণের স্থির ব্লকের কার্য সম্পাদনের আদেশ

আমি জাভা এনামের স্ট্রিংয়ের মান থেকে কীভাবে সন্ধান করব


4
জোশুয়া ব্লচ যদি এটি বলে থাকে তবে এটিই একমাত্র উপায় :-)। এটি একটি লজ্জাজনক বিষয় যে আমাকে সর্বদা এখানে স্ক্রোল করতে হবে।
dermoritz

11
এটি আপনি জাভা 8- Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity()))তেও সহজতর করতে পারেন: আমিও স্ট্রিং () (কন্সট্রাক্টরের মাধ্যমে পাস করা) ওভাররাইড করার এবং নামের পরিবর্তে এটি ব্যবহার করার পরামর্শ দিচ্ছি, বিশেষত এনুম সিরিয়ালীকরণযোগ্য ডেটার সাথে যুক্ত কারণ এটি আপনাকে না দিয়ে কেসিং নিয়ন্ত্রণ করতে দেয় সোনার ফিট।
নভেটারটা

1
জাভা 8 অবশ্যই এই ফোরামে (আরও ভাল) উত্তর পরিবর্তন করতে পারে / করতে পারে। লেজ (সোনার) কুকুর (অ্যাপ্লিকেশন কোড) ওয়াগ করার বিষয়ে নিশ্চিত না।
ড্যারেল টিগু

3
যদি আপনি unmodifiableMapযাইহোক এটি এড়াতে যাচ্ছেন , তবে এটি দিয়ে আর কোনও লাভ নেই ConcurrentHashMap। শুধু একটি ব্যবহার করুন HashMap। (আপনার যদি পেয়ারা থাকে ImmutableMapতবে আমি তার পরিবর্তে
এটির

9
স্ট্যাটিক ইনিশিয়ালাইজেশন সহজাতভাবে সিঙ্ক্রোনাইজ করা হয় , সুতরাং ConcurrentHashMapএখানে ব্যবহার করার একেবারেই কারণ নেই, যেখানে মানচিত্র আরম্ভের পরে আর কখনও পরিবর্তন হয় না। সুতরাং কেন এমনকি উদাহরণস্বরূপ জেএলএসে নিজেই একটি নিয়মিত ব্যবহার করে HashMap
রেডিওডেফ

74

আপনার কেস সম্পর্কে আপনারও যত্নবান হওয়া উচিত। আমাকে বোঝাতে দাও: Blah.valueOf("A")কাজ করছে , কিন্তু Blah.valueOf("a")কাজ করবে না। তারপর আবার Blah.valueOf("a".toUpperCase(Locale.ENGLISH))কাজ করবে।

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

edit2 অ্যান্ড্রয়েডে আপনার ব্যবহার করা উচিত Locale.US, যেমন সুলাই পয়েন্ট করে


6
ডিফল্ট লোকাল থেকে সাবধান থাকুন!
টিসি।

3
আপনার অ্যান্ড্রয়েড ব্যবহারকারীদের জন্য, আমি এখানে উল্লেখ করতে চাই যে অ্যান্ড্রয়েড ডকুমেন্টেশনLocale.US মেশিনে পঠনযোগ্য ইনপুট / আউটপুট ব্যবহারের জন্য স্পষ্টভাবে উত্সাহ দেয় ।
সোলাই

2
হ্যাঁ, দুর্ভাগ্যক্রমে তুরস্ক একটি ভাল উদাহরণ। এটি জাভার ভাঙ্গা ডিফল্ট চার্সেটের হ্যান্ডলিংয়ের সাথে একত্রিত করুন (ইউনিকোডের পরিবর্তে উইন্ডোজে লাতিনে ডিফল্ট) এবং আপনি চারসেট বা লোকেল গ্রহণের পদ্ধতিগুলির ডিফল্ট সংস্করণগুলি প্রায় সর্বদা অনিরাপদ দেখতে পাবেন। আপনার প্রায় সর্বদা স্পষ্টভাবে তাদের সংজ্ঞা দেওয়া উচিত should
স্টিজন ডি উইট

নিশ্চিত নয় যে জাভার "ডিফল্ট" অক্ষরগুলি এবং সেটের তুলনায় "ভাঙ্গা" রয়েছে তবে মঞ্জুরিপ্রাপ্ত, ওভাররাইডের পরিবর্তে ইউটিএফ -8 এ ডিফল্ট (যা সর্বদা স্পষ্ট করে দেখা উচিত) জুনিয়র প্রোগ্রামারদের যারা সাধারণত বুঝতে ব্যর্থ হন তাদের জন্য আরও ভাল সিস্টেম তৈরি করতে পারত চরসেট ধারণা।
ড্যারেল টিগু

38

এখানে এমন একটি পদ্ধতি রয়েছে যা এটি কোনও এনুমের জন্য করতে পারে এবং এটি সংবেদনশীল।

/** 
 * 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
স্টিজন ডি উইট

ক্ষেত্রে সংবেদনশীলতার মতো তবে ... কীগুলির জন্য এনামস ওভারকে (এলোমেলো) স্ট্রিং অ্যাসাইনমেন্টগুলি পছন্দ করুন এবং ... ছোট্ট তবে পুনরাবৃত্তকরণ যেমন সম্ভাব্য পুনরাবৃত্ত অনুসন্ধানের জন্য কম পারফরম্যান্ট। অতএব EnumMap এট ইমেল।
ড্যারেল টিগু

এটা কাজ করে না ! আমি আমার উদ্দেশ্য সমান ইগনোরকেসকে সমানতে পরিবর্তন করেছি। উভয় সমতুল্য ইনপুটগুলি হুবহু হলেও কোডটি ব্যর্থ হয়েছিল।
মাস্টারজয়ে 2

36

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


1
কেস সংবেদনশীল, সহায়তা করছে না!
মুর্তজা কাঁচওয়ালা

@ মুর্তজাকঞ্চওয়ালা আপনি কি নিজের মন্তব্য পরিষ্কার করতে পারবেন? আপনি কি করতে চেষ্টা করছেন?
পিটার লরি

2
হাই @ পিটারলাউরে, আমি একটি স্ট্রিং পাবলিক এনাম অবজেক্টটাইপ {পার্সন ("ব্যক্তি") পাবলিক স্ট্রিং প্যারামিটারনাম থেকে এনাম আনার উদ্দেশ্যে যাচ্ছিলাম; অবজেক্টটাইপ (স্ট্রিং প্যারামিটারনাম) {this.parameterName = parameterName; } পাবলিক স্ট্রিং getParameterName () this this.parameterName ফিরিয়ে দিন; } স্ট্রিং (স্ট্রিং প্যারামিটারনাম) থেকে পাবলিক স্ট্যাটিক অবজেক্টটাইপ {যদি (প্যারামিটারনেম! = নাল) {(অবজেক্টটাইপ অবজেক্ট টাইপ: অবজেক্টটাইপ.ভালিউস ()) {যদি (প্যারামিটারনেম.ইকিয়ালস আইগনোর কেস (Tজেক্টটাইপ.প্রেমিটারনেম) {রিটার্ন অবজেক্টটাইপ; }}} নাল ফিরে; }}
মুর্তজা কাঁচওয়ালা

34

জাভা 8 বা তারপরে , স্ট্রিম ব্যবহার করে :

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

নিশ্চিত না যে এটি কোনওরকম আরও ভাল উত্তর। এই ক্ষেত্রে স্ট্রিমগুলি হ'ল সমস্ত মানগুলির চেয়ে অন্যের মতো একক থ্রেডযুক্ত পুনরাবৃত্তকারী এবং মানচিত্রের অনুসন্ধানের ইমপ্লের চেয়ে তর্কযুক্ত কম পারফরম্যান্ট। মাল্টি-থ্রেড প্রসঙ্গে স্ট্রিমগুলির আরও মান রয়েছে যেখানে উদাহরণস্বরূপ, একটি নতুন লাইন-বিচ্ছিন্ন পাঠ্য ফাইলটির সমান্তরাল সম্পাদন কার্যকারিতা উন্নত করতে পারে।
ড্যারেল টিগু

28

আপনি যদি নিজের নিজস্ব ইউটিলিটি লিখতে না চান তবে গুগলের ব্যবহার করুন গ্রন্থাগার:

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

জাভা ফাংশনে অন্তর্নির্মিতের বিপরীতে এটি আপনাকে পরীক্ষা করতে পারে যে ব্লাহে উপস্থিত রয়েছে এবং কোনও ব্যতিক্রম ছুঁড়ে না ফেলে।


7
দু: খিত অংশ, এই আয় একটি Google ঐচ্ছিক এবং জাভা ঐচ্ছিক নয়
javaProgrammer

সত্য। বহিঃপ্রকাশিত যদিও। গুগল এবং নেটফ্লিক্সের দুর্দান্ত জাভা লিব রয়েছে। যেখানে নতুন সংস্করণে জাভা ক্যাচ-আপ ক্লাস প্রয়োগ করা অনিবার্যভাবে সমস্যার কারণ হয়ে উঠেছে over একধরনের বিক্রেতার কাছে সব ধরনের থাকতে হবে।
ড্যারেল টিগু

26

আমার 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. হেডারপ্যারাম টিকাতে সরাসরি ধরণের রূপান্তর

1
বিকল্পভাবে আপনাকে আরও পঠনযোগ্য switchব্লক লেখার অনুমতি দেওয়ার জন্য আপনি এর .orElse(null)পরিবর্তে ক্লজটিতে .orElseThrow()থাকা ব্যতিক্রমটিকে কোড করতে পারেন default- এবং প্রয়োজনের সময় আরও দরকারী তথ্য অন্তর্ভুক্ত করতে পারেন। এবং এটিকে আরও হালকা করার জন্য আপনি ব্যবহার করতে পারেনv -> Objects.equals(v.name, s == null ? "" : s.trim().toUpperCase())
অ্যাডাম

অথবা কেবল তার Optionalথেকে ফিরে findFirst().orElse(null)orElseThrow()
যাবেন

1
একটি ঘোষণা public static MyEnum valueOf(String)করা আসলে একটি সংকলন ত্রুটি, যেহেতু এটি স্পষ্টভাবে সংজ্ঞায়িত হিসাবে একই, তাই আপনার উত্তরের পুরানো সংস্করণটি আসলে আরও ভাল। ( জেএলএস , আইডোন )
রেডিওডেফ

আমার বিকল্পে ব্যতিক্রমগুলি এড়ানো এবং ptionচ্ছিক ব্যবহার করা ভাল। তার পরে আমাদের নাল বাতিল করা উচিত এবং এর পরিবর্তে ptionচ্ছিক ব্যবহার করা উচিত।
হ্যান্স শ্রেইডার

আবার, কেবল মনে রাখবেন যে কম বা আরও ভাল দেখাচ্ছে কোড ... এমনকি এর মতো একটি স্ট্রিম বাস্তবায়ন মানচিত্রের অনুসন্ধান (কম পারফরম্যান্ট) বনাম সমস্ত মানগুলির মধ্যে কেবল একটি পুনরাবৃত্তি।
ড্যারেল টিগু

16

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

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

এটি আপনাকে স্ট্রিংফাইড এনাম নাম দিয়ে মান প্রদান করবে যেমন উদাহরণস্বরূপ আপনি যদি এনাম নাম থেকে "ব্যক্তি" সরবরাহ করেন তবে এটি আপনাকে এনামের মান অর্থাৎ "ব্যক্তি" ফিরিয়ে দেবে


13

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 টি উদাহরণ


7
এটি মূলত valueOfআপনার জন্য কি করে। এই স্থিতিশীল পদ্ধতি অতিরিক্ত, ব্যতিক্রম এবং সমস্ত কিছু সরবরাহ করে না। তারপরে যদি / অন্য নির্মাণগুলি অত্যন্ত বিপজ্জনক ... যে কোনও নতুন এনাম ধ্রুবক যুক্ত হওয়া এই পদ্ধতিটি কোনও পরিবর্তন ছাড়াই ভেঙে দেবে।
YoYo

: এছাড়াও কিভাবে আমরা একটি মামলা অবশ লুকআপ করছেন জন্য valueOf ব্যবহার করতে পারেন, বা কিভাবে আমরা এটা ব্যতিক্রম এবং চাকরী alias লেখা এড়াতে পারেন এই উদাহরণ বিবেচনা করুন বিকল্প নাম প্রদান stackoverflow.com/a/12659023/744133
Yoyo

2
name()স্থির নয়।
nrubin29

10

পেয়ারা লাইব্রেরি ব্যবহার করে সমাধান। পদ্ধতি getPlanet () কেস সংবেদনশীল, সুতরাং getPlanet ("MerCUrY") প্ল্যানেট প্রত্যাবর্তন করবে MMERCURY।

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

8

পূর্ববর্তী উত্তরগুলি যুক্ত করতে এবং নাল এবং এনপিই-র কাছাকাছি কিছু আলোচনার সমাধান করতে আমি অনুপস্থিত / অবৈধ মামলাগুলি পরিচালনা করতে পেয়ারা বিকল্পগুলি ব্যবহার করছি। এটি ইউআরআই / পরামিতি পার্সিংয়ের জন্য দুর্দান্ত কাজ করে।

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

যাদের সচেতন নয় তাদের জন্য এখানে Forচ্ছিক সহ নাল এড়ানো সম্পর্কে আরও কিছু তথ্য রয়েছে: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained# বিকল্প


এটি এনামের অভ্যন্তরে সম্পর্কিত নিদর্শন এবং Oচ্ছিক ব্যবহারের জন্য সত্যই উত্তম উত্তর - এনামগুলি খুব ক্লাস হয় এবং এই পদ্ধতিগুলি, ওভাররাইড পদ্ধতি ইত্যাদি দ্বারা সজ্জিত করা যায়, এহেতু এটি সাবলীল শৈলীর প্রোগ্রামিংয়ের জন্যও একটি ভাল ক্ষেত্রে is পদ্ধতিগুলি থেকে ফিরে আসা নালগুলি বগিটি তৈরি করে (পদ্ধতি কলগুলির ফ্লুয়েন্ট চেইনে অজানা স্থানে এনপিই)।
ড্যারেল টিগু

8

জাভা 8 এ স্থিতিশীল মানচিত্রের প্যাটার্নটি আরও সহজ এবং এটি আমার প্রিফার্ড পদ্ধতি। আপনি যদি জ্যাকসনের সাথে এনাম ব্যবহার করতে চান তবে আপনি টু স্ট্রিংকে ওভাররাইড করতে পারেন এবং নামের পরিবর্তে সেটি ব্যবহার করতে পারেন, তারপরে এনোটেট করুন@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);
    }
}

জ্যাকসন একটি জেএসএন (জাভাস্ক্রিপ্ট অবজেক্ট নোটেশন) বাস্তবায়ন। আসল প্রশ্নের জেএসওএন এর সাথে কোনও সম্পর্ক ছিল না।
ড্যারেল টিগু

জেএসএন অংশটি তখনকার সময়ে আমি কেবল প্রাসঙ্গিক বলে মনে করতাম, কারণ একটি স্ট্রিং থেকে এনাম পাওয়া মূলত একধরণের ডিসরিয়ালাইজেশন এবং জেএসএন / জ্যাকসন সম্ভবত সর্বাধিক জনপ্রিয় সিরিয়ালাইজেশন সমাধান।
নভেটরতা

মডারেটেশন দিক থেকে বুঝতে পারুন - এটি ওপির প্রশ্নের উত্তর দেওয়ার ক্ষেত্রে অবদান রাখেনি তাই কেবল প্রসঙ্গটি সেখানে সেট করতে সহায়তা করার চেষ্টা করেছিল। জ্যাকসন জ্যাকসনের সাথে জাভায় অবজেক্টগুলিকে ক্যানোনিকাল আকারে রূপান্তরিত করার উপায় হ'ল জ্যাকসন একটি দুর্দান্ত গ্রন্থাগার হওয়ায়।
ড্যারেল টিগু

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

: চালু stackoverflow.com উত্তর ও প্রশ্ন জিজ্ঞাসা নির্দেশিকা জন্য এই লিঙ্কে কটাক্ষপাত করা stackoverflow.com/faq
bakoyaro

1
এটি জোসেমি'র উত্তর হিসাবে কম-বেশি একই
রুপ

6

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

}

শূন্য নোট করুন (0) এবং একটি (1) সনাক্তকারী অপ্রয়োজনীয়। এনাম মানগুলি () পদ্ধতি সদস্যদের কোডড হিসাবে একই ক্রমে ফিরিয়ে দেবে। সুতরাং প্রথম এন্ট্রি হবে অর্ডিনাল শূন্য, দ্বিতীয় এক ইত্যাদি
ড্যারেল টিগু

6

এনুম খুব দরকারী, আমি 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");

1
এনামদের আরও ধাক্কা দেওয়ার জন্য ভাল উদাহরণ। মানচিত্রে স্ট্যান্ডার্ড স্ট্যাটিক নামগুলি এবং লুক্কিট ব্যবহার করে ভাষা-এনকোডিং তৈরি করতেন তবে এখনও মূলত একই লজিক্যাল মানটির জন্য বিভিন্ন ট্যাগ সহ এনাম থাকার একটি ভাল উদাহরণ।
ড্যারেল টিগু

5

কি সম্পর্কে?

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

4

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()পদ্ধতি ফেরৎ একটি Enum ধ্রুবক Gender.MALE, যে আয় নাম কলিং "MALE"


4

অ্যাপাচি এর কমন্স-ল্যাং লাইব্রেরিতে একটি স্থির ফাংশন রয়েছে org.apache.commons.lang3.EnumUtils.getEnum যা আপনার এনুম টাইপের একটি স্ট্রিং মানচিত্র তৈরি করবে। জেফরি হিসাবে মূলত একই উত্তর কিন্তু বারণের মধ্যে ইতিমধ্যে যখন আপনার নিজের রোল কেন।


1
সুষ্ঠু মন্তব্য (ডিআরওয়াই) তবে ... যদিও বেশিরভাগ অ্যাপাচি কমন্স স্টাফ দুর্দান্ত, আমি সেই বেসটিতে বেশ কয়েকটি বাগ এবং অ্যান্টি-প্যাটার্ন পেয়েছি। সুতরাং জোশুয়া ব্লচের বাস্তবায়ন আরও দৃ stronger় হতে পারে বলে উল্লেখ করে। কেউ কী প্রয়োগ করেছে তা জানতে অ্যাপাচি কোড পর্যালোচনা করে ততক্ষণে নীচে যান। যদি বলা হয় যে বিখ্যাত ডগ লিহ যিনি জাভা চুক্তি পুনরায় লিখেছেন ... তবে আমি এটিকে পুরোপুরি বিশ্বাস করব।
ড্যারেল টিগু

4

একটি সহায়ক ইউটিলিটি সহ শীর্ষের রেট করা উত্তরে যুক্ত করা হচ্ছে ...

valueOf() এটির ইনপুট পছন্দ না করে এমন ক্ষেত্রে দুটি পৃথক ব্যতিক্রম ছোঁড়ে।

  • IllegalArgumentException
  • NullPointerExeption

যদি আপনার প্রয়োজনীয়তাগুলি এমন হয় যে আপনার স্ট্রিং অবশ্যই একটি এনাম মানের সাথে মেলে এমন কোনও গ্যারান্টি নেই আপনার উদাহরণস্বরূপ, যদি স্ট্রিং ডেটাবেস থেকে আসে এবং এনামের পুরাতন সংস্করণ থাকতে পারে তবে আপনাকে এগুলি পরিচালনা করতে হবে প্রায়ই ...

সুতরাং আমি এখানে একটি পুনর্ব্যবহারযোগ্য পদ্ধতি যা আমাদের লিখেছিল যা আমাদের ডিফল্ট এনামকে ফেরত দেওয়ার সংজ্ঞা দেয় যদি আমরা পাস করা স্ট্রিংটি মেলে না।

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
}

2

হিসেবে switch-version উল্লেখ করা হয় নি এখনো আমি এটা চালু (ওপি এর 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ইন্টারফেসের নকশা গ্রহণ করে যা Map.getOrDefault(Object key, V defaultValue)জাভা 8 হিসাবে একটি পদ্ধতি সরবরাহ করে ।


1

বিপরীত উপায়ে ক্যাপচার করা অন্য ইউটিলিটি। একটি মান ব্যবহার করে যা সনাক্ত করে যে এনুম, তার নাম থেকে নয়।

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


1

কোটলিন সলিউশন

একটি এক্সটেনশন তৈরি করুন এবং তারপরে কল করুন 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)এবং নাল প্রতিক্রিয়া এড়ানো। ডিফল্ট স্বয়ংক্রিয় হওয়ার জন্য আপনি আপনার নির্দিষ্ট এনাম প্রসারিত করতে পারেন

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

আপনি কি মনে করেন যে এখানে আপনার উত্তরের আরও ভাল বাড়ি থাকবে? stackoverflow.com/questions/28548015/...
nabster

0

আমি এই ধরণের প্রক্রিয়াটি কমান্ডগুলিকে গণনার ক্ষেত্রে স্ট্রিং হিসাবে পার্স করতে ব্যবহার করতে চাই। আমার কাছে সাধারণত "অজানা" হিসাবে একটি গণনা থাকে সুতরাং অন্যরা যখন খুঁজে পাওয়া যায় না তখন এটি ফিরে আসতে সহায়তা করে (এমনকি কোনও ক্ষেত্রে সংবেদনশীলতার ভিত্তিতে) শূন্যের পরিবর্তে (যার কোনও মূল্য নেই)। সুতরাং আমি এই পদ্ধতির ব্যবহার।

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

-1

এনামের নাম নেওয়ার দ্রুততম উপায় হ'ল অ্যাপ্লিকেশন শুরু হওয়ার সাথে সাথে এনাম টেক্সট এবং মানটির একটি মানচিত্র তৈরি করা এবং নামটি বেলাহ।

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());
    } 
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.