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


164

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

public enum Verbosity {

    BRIEF, NORMAL, FULL;

    private static Map<String, Verbosity> stringMap = new HashMap<String, Verbosity>();

    private Verbosity() {
        stringMap.put(this.toString(), this);
    }

    public static Verbosity getVerbosity(String key) {
        return stringMap.get(key);
    }
};

আইআইআরসি, এটি একটি এনপিই দেয় কারণ স্থির সূচনাটি নীচে ডাউন হয়ে যায় (অর্থাত্ শীর্ষে এনাম কনস্ট্যান্টগুলি এটি stringMapআরম্ভের নীচে নামার আগে তৈরি করা হয়)। স্বাভাবিক সমাধান হল নেস্টেড ক্লাস ব্যবহার করা।
টম হাটিন - 21

এই ধরণের দ্রুত প্রতিক্রিয়ার জন্য আপনাকে ধন্যবাদ। (এফডাব্লুআইডাব্লু আমি এই সমস্যার জন্য সান জাভাদোকগুলি খুব দরকারী বলে খুঁজে পাইনি)।
peter.murray.rust

এটি একটি লাইব্রেরির ইস্যুর চেয়ে সত্যিই একটি ভাষার সমস্যা। তবে আমি মনে করি এপিআই ডকসগুলি জেএলএসের চেয়ে বেশি পড়েন (যদিও সম্ভবত ভাষা ডিজাইনারদের দ্বারা নয়), তাই জাভা.এলং ডক্সে এই জাতীয় জিনিসের সম্ভবত আরও বেশি গুরুত্ব থাকতে হবে।
টম হাটিন -

উত্তর:


241

valueOfপ্রতিটি এনুমের জন্য স্বয়ংক্রিয়ভাবে তৈরি করা পদ্ধতিটি ব্যবহার করুন ।

Verbosity.valueOf("BRIEF") == Verbosity.BRIEF

যথেচ্ছ মানগুলির জন্য এইটি শুরু করুন:

public static Verbosity findByAbbr(String abbr){
    for(Verbosity v : values()){
        if( v.abbr().equals(abbr)){
            return v;
        }
    }
    return null;
}

আপনার প্রোফাইলার যদি আপনাকে বলেন তবে কেবল মানচিত্রের প্রয়োগে পরে যান।

আমি জানি এটি সমস্ত মানগুলির সাথে পুনরাবৃত্তি করছে, তবে কেবল 3 টি এনাম মানগুলির সাথে এটি অন্য কোনও প্রচেষ্টার পক্ষে কমই সত্য, যদি আপনার কাছে প্রচুর মান না থাকে তবে আমি মানচিত্রে বিরক্ত না করাই এটি যথেষ্ট দ্রুত হবে।


ধন্যবাদ - এবং আমি মানগুলি এখনও পৃথক জানতে
পারলে

আপনি "v.abbr ()" এর পরিবর্তে "v.abbr.equals ..." ব্যবহার করতে পারেন তাই ক্লাস মেম্বার 'abbr' এ অ্যাক্সেস করতে পারবেন।
Amio.io

7
এছাড়াও, স্বেচ্ছাচারিত মানগুলির জন্য (দ্বিতীয় কেস) IllegalArgumentExceptionনাল ফেরার পরিবর্তে একটি নিক্ষেপ বিবেচনা করুন ( অর্থাত্ যখন কোনও মিল খুঁজে পাওয়া যায় না) - জেডি কে এভাবেই করে Enum.valueOf(..)
প্রিয়দু নিমরে

135

আপনি কাছাকাছি। যথেচ্ছ মানগুলির জন্য, নিম্নলিখিতগুলির মতো কিছু চেষ্টা করুন:

public enum Day { 

    MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
    THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;

    private final String abbreviation;

    // Reverse-lookup map for getting a day from an abbreviation
    private static final Map<String, Day> lookup = new HashMap<String, Day>();

    static {
        for (Day d : Day.values()) {
            lookup.put(d.getAbbreviation(), d);
        }
    }

    private Day(String abbreviation) {
        this.abbreviation = abbreviation;
    }

    public String getAbbreviation() {
        return abbreviation;
    }

    public static Day get(String abbreviation) {
        return lookup.get(abbreviation);
    }
}

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

7
@ অ্যাডাম জেন্ট: জেএলএসের নীচে একটি লিঙ্ক রয়েছে যেখানে এই নিখুঁত নির্মাণের উদাহরণ হিসাবে উপস্থিত করা হয়েছে। এটি বলে যে স্থির সূচনাটি
সেলেনা

3
হ্যাঁ জাভা 8 এর মতো আধুনিক জাভা স্মৃতি মডেলটি স্থির করেছে। বলা হচ্ছে যে জেরবেলের মতো হট অদলবদল এজেন্টরা এখনও গোলযোগ পেয়ে যায় যদি আপনি বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সের কারণে সূচনাটি এম্বেড করেন।
অ্যাডাম জেন্ট

@ অ্যাডাম জেন্ট: হুমম। আমি প্রতিদিন নতুন কিছু শিখি. [বুটস্ট্র্যাপ সিঙ্গলেটনের সাথে আমার এনামগুলিকে রিফ্যাক্টর করার জন্য নিঃশব্দে ঝাঁকুনি দিয়ে ...] দুঃখিত এটি যদি একটি বোকা প্রশ্ন, তবে এটি কি বেশিরভাগ স্থির সূচনা নিয়ে সমস্যা?
সেলিনা 15

আমি স্ট্যাটিক কোড ব্লক সমস্যা কখনো দেখিনি সক্রিয়া করা হচ্ছে না, কিন্তু আমি শুধু আমি শুধু একটু বেঞ্চমার্ক JMH 1.22 ব্যবহার করে এবং একটি ব্যবহার করেনি যেহেতু আমি জাভা শুরু জাভা 8 ব্যবহার করেছেন 2015 সালে, HashMap<>সঞ্চয় করতে enums হতে প্রমাণিত দুর্বল লুপের চেয়ে 40% এরও বেশি দ্রুত
সিব্লদান

21

জাভা 8 এর মাধ্যমে আপনি এইভাবে অর্জন করতে পারেন:

public static Verbosity findByAbbr(final String abbr){
    return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}

আমি ফিরে আসার চেয়ে একটি ব্যতিক্রম নিক্ষেপ করব null। তবে এটি ব্যবহারের ক্ষেত্রেও নির্ভর করে
আলেকজান্ডার

12

@ লাইলের উত্তরটি বরং বিপজ্জনক এবং আমি দেখেছি এটি কার্যকর হয় না বিশেষত যদি আপনি এনামকে একটি স্থিতিশীল অভ্যন্তর শ্রেণি করেন। পরিবর্তে আমি এই জাতীয় কিছু ব্যবহার করেছি যা এনামগুলিতে বুটস্ট্র্যাপসিংলেটনের মানচিত্র লোড করবে।

সম্পাদনা করুন এই একটা সমস্যা আধুনিক JVMs (জেভিএম 1.6 বা তার অধিক) সঙ্গে আর কোনো করা উচিত হবে না কিন্তু আমি মনে করি এখনও JRebel সঙ্গে বিষয় আছে কি কিন্তু আমি পুনঃপরীক্ষা এটি একটি সুযোগ ছিল না

আমাকে আগে লোড করুন:

   public final class BootstrapSingleton {

        // Reverse-lookup map for getting a day from an abbreviation
        public static final Map<String, Day> lookup = new HashMap<String, Day>();
   }

এখন এটি এনাম কনস্ট্রাক্টরে লোড করুন:

   public enum Day { 
        MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
        THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;

        private final String abbreviation;

        private Day(String abbreviation) {
            this.abbreviation = abbreviation;
            BootstrapSingleton.lookup.put(abbreviation, this);
        }

        public String getAbbreviation() {
            return abbreviation;
        }

        public static Day get(String abbreviation) {
            return lookup.get(abbreviation);
        }
    }

যদি আপনার অভ্যন্তরীণ এনাম থাকে তবে আপনি কেবল এনাম সংজ্ঞাটির উপরে মানচিত্রটি সংজ্ঞায়িত করতে পারেন এবং এটি (তত্ত্ব অনুসারে) আগে লোড হওয়া উচিত।


3
"বিপজ্জনক" এবং কেন একটি অভ্যন্তরীণ শ্রেণি বাস্তবায়নের বিষয়টি গুরুত্বপূর্ণ তা নির্ধারণ করা দরকার। এটি শীর্ষ-থেকে-নীচে স্থিতিশীল সংজ্ঞা ইস্যুতে আরও কাজ করে তবে এই প্রশ্নের সাথে সম্পর্কিত লিঙ্কের সাথে অন্য সম্পর্কিত উত্তরে কার্যকরী কোড রয়েছে যা এনাম উদাহরণে একটি স্থির মানচিত্র ব্যবহার করে ব্যবহারকারী-সংজ্ঞায়িত মান থেকে "get" পদ্ধতিটি ব্যবহার করে এনাম টাইপ। stackoverflow.com/questions/604424/lookup-enum-by-string-value
ড্যারেল টিগু

2
@ ড্যারেলটাইগ মূল সমস্যাটি পুরানো জেভিএম (প্রথম 1.6 পূর্ববর্তী) বা অন্যান্য জেভিএম (আইবিএম) বা হটকোড সোয়াপারস (জেআরবেল) এর কারণে হয়েছিল was আধুনিক জেভিএমগুলিতে সমস্যাটি হওয়া উচিত নয় যাতে আমি কেবল আমার উত্তরটি মুছতে পারি।
আদম ভদ্দরলোকের

মনে রাখা ভাল যে কাস্টম সংকলক বাস্তবায়ন এবং রানটাইম অপ্টিমাইজেশনের কারণে সত্যই এটি সম্ভব ... অর্ডারিংটি অনুরূপ হতে পারে, যার ফলে একটি ত্রুটি হয়। তবে এটি অনুমানের লঙ্ঘন করে to
ড্যারেল টিগু

7

এবং আপনি valueOf () ব্যবহার করতে পারবেন না ?

সম্পাদনা: বিটিডব্লিউ, এনামে আপনাকে স্ট্যাটিক using using ব্যবহার করা থেকে বিরত করার কিছুই নেই।


অথবা valueOfএনাম ক্লাসে সিন্থেটিক , সুতরাং আপনার এনাম ক্লাস নির্দিষ্ট করার দরকার নেই Class
টম হাটিন - 21

অবশ্যই এটিতে জাভাডোক এন্ট্রি ছিল না তাই এটির লিঙ্ক করা শক্ত।
ফ্রেডরিক

1
আপনি valueOf () ব্যবহার করতে পারেন তবে নামটি অবশ্যই এনাম ডিক্লোরেশনের সেই সেটটির সাথে মিলবে। উপরের দুটি দেখার পদ্ধতিগুলির মধ্যে দুটিই .equalsIgnoreCase () ব্যবহার করার জন্য পরিবর্তন করা যেতে পারে এবং ত্রুটিতে আরও কিছুটা দৃ little়তা থাকে।

@ লিওনার্দো ট্রু যদি এটি দৃust়তা যোগ করে বা কেবল দোষ-সহনশীলতা বিতর্কযোগ্য। বেশিরভাগ ক্ষেত্রেই আমি বলব এটি পরেরটি এবং সেক্ষেত্রে এটি অন্য কোথাও পরিচালনা করা ভাল এবং এখনও এনামের মানফল () ব্যবহার করা ভাল।
ফ্রেডরিক

4

যদি এটি অন্যকে সহায়তা করে তবে আমি যে বিকল্পটি পছন্দ করি তা এখানে লিখিত নয়, যা পেয়ারার মানচিত্রের কার্যকারিতা ব্যবহার করে :

public enum Vebosity {
    BRIEF("BRIEF"),
    NORMAL("NORMAL"),
    FULL("FULL");

    private String value;
    private Verbosity(final String value) {
        this.value = value;
    }

    public String getValue() {
        return this.value;
    }

    private static ImmutableMap<String, Verbosity> reverseLookup = 
            Maps.uniqueIndex(Arrays.asList(Verbosity.values()), Verbosity::getValue);

    public static Verbosity fromString(final String id) {
        return reverseLookup.getOrDefault(id, NORMAL);
    }
}

আপনি যে ডিফল্টটি ব্যবহার করতে পারেন তার সাহায্যে nullআপনি throw IllegalArgumentExceptionবা আপনার যে কোনও আচরণ পছন্দ fromStringকরতে পারেন returnOptional


3

জাভা 8 যেহেতু আপনি একক লাইনে এবং স্ট্যাটিক ব্লক ছাড়াই মানচিত্রটি আরম্ভ করতে পারবেন

private static Map<String, Verbosity> stringMap = Arrays.stream(values())
                 .collect(Collectors.toMap(Enum::toString, Function.identity()));

+1 স্ট্রিমের দুর্দান্ত ব্যবহার এবং পাঠযোগ্যতার ত্যাগ ছাড়াই খুব সংক্ষিপ্ত! আমি এর Function.identity()আগে এই ব্যবহারটি দেখিনি , আমি এটির চেয়ে অনেক বেশি টেক্সটিকভাবে আবেদনময়ী মনে করি e -> e
মাতসু প্র।

0

সম্ভবত, এই একবার দেখুন। এটা আমার জন্য কাজ করে। এর উদ্দেশ্য হ'ল '/ লাল' রঙের সাথে 'রেড' অনুসন্ধান করা। কোনওটি ঘোষণা করা static mapএবং enumএর মধ্যে গুলি একবারে লোড করা যদি কিছুগুলি হয় তবে কিছু কার্যকারিতা সুবিধা নিয়ে আসে enum

public class Mapper {

public enum Maps {

    COLOR_RED("/red_color", "RED");

    private final String code;
    private final String description;
    private static Map<String, String> mMap;

    private Maps(String code, String description) {
        this.code = code;
        this.description = description;
    }

    public String getCode() {
        return name();
    }

    public String getDescription() {
        return description;
    }

    public String getName() {
        return name();
    }

    public static String getColorName(String uri) {
        if (mMap == null) {
            initializeMapping();
        }
        if (mMap.containsKey(uri)) {
            return mMap.get(uri);
        }
        return null;
    }

    private static void initializeMapping() {
        mMap = new HashMap<String, String>();
        for (Maps s : Maps.values()) {
            mMap.put(s.code, s.description);
        }
    }
}
}

আপনার মতামত রাখুন দয়া করে।


-1

আপনি আপনার এনামকে নিম্নলিখিত কোড হিসাবে সংজ্ঞায়িত করতে পারেন:

public enum Verbosity 
{
   BRIEF, NORMAL, FULL, ACTION_NOT_VALID;
   private int value;

   public int getValue()
   {
     return this.value;
   } 

   public static final Verbosity getVerbosityByValue(int value)
   {
     for(Verbosity verbosity : Verbosity.values())
     {
        if(verbosity.getValue() == value)
            return verbosity ;
     }

     return ACTION_NOT_VALID;
   }

   @Override
   public String toString()
   {
      return ((Integer)this.getValue()).toString();
   }
};

আরও স্পষ্টতার জন্য নীচের লিঙ্কটি দেখুন


-1

আপনি যদি কোনও ডিফল্ট মান চান এবং অনুসন্ধান মানচিত্র তৈরি করতে না চান, আপনি এটি পরিচালনা করতে একটি স্ট্যাটিক পদ্ধতি তৈরি করতে পারেন। এই উদাহরণটি এমন লুকও পরিচালনা করে যেখানে প্রত্যাশিত নামটি একটি সংখ্যার সাথে শুরু হবে।

    public static final Verbosity lookup(String name) {
        return lookup(name, null);
    }

    public static final Verbosity lookup(String name, Verbosity dflt) {
        if (StringUtils.isBlank(name)) {
            return dflt;
        }
        if (name.matches("^\\d.*")) {
            name = "_"+name;
        }
        try {
            return Verbosity.valueOf(name);
        } catch (IllegalArgumentException e) {
            return dflt;
        }
    }

যদি আপনার এটির গৌণ মান প্রয়োজন হয় তবে আপনি অন্য উত্তরগুলির মতো প্রথমে দেখার মানচিত্রটি তৈরি করবেন।


-1
public enum EnumRole {

ROLE_ANONYMOUS_USER_ROLE ("anonymous user role"),
ROLE_INTERNAL ("internal role");

private String roleName;

public String getRoleName() {
    return roleName;
}

EnumRole(String roleName) {
    this.roleName = roleName;
}

public static final EnumRole getByValue(String value){
    return Arrays.stream(EnumRole.values()).filter(enumRole -> enumRole.roleName.equals(value)).findFirst().orElse(ROLE_ANONYMOUS_USER_ROLE);
}

public static void main(String[] args) {
    System.out.println(getByValue("internal role").roleName);
}

}


-2

Enum::valueOf()উপরের গ্যারেথ ডেভিস ও ব্র্যাড ম্যাসের পরামর্শ অনুসারে আপনি এই ফাংশনটি ব্যবহার করতে পারেন , তবে নিশ্চিত হয়ে নিন IllegalArgumentExceptionযে ব্যবহৃত স্ট্রিং এনামের মধ্যে উপস্থিত না থাকলে আপনি এটি নিক্ষেপ করেছেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.