জাভা এনামে মান () এবং টুস্ট্রিং () ওভাররাইড করুন


122

আমার মানগুলিতে enumশব্দগুলি যা তাদের মধ্যে ফাঁকা স্থান থাকা দরকার, তবে এনামগুলিতে তাদের মানগুলিতে ফাঁকা স্থান থাকতে পারে না তাই এটি সমস্ত কিছু আপ হয়। toString()যেখানে আমি এটি বলি সেখানে এই স্পেসগুলি যুক্ত করতে আমি ওভাররাইড করতে চাই ।

আমি যখন চাই আমি valueOf()একই স্ট্রিংয়ের সাথে স্পেস যুক্ত করেছি তখন এনাম সঠিক এনাম সরবরাহ করতে চাই।

উদাহরণ স্বরূপ:

public enum RandomEnum
{
     StartHere,
     StopHere
}

যার মান ফেরতের স্ট্রিং তা কল toString()করুন । একই স্ট্রিং ( ) এ কল করুন এনাম মান প্রদান করে ।RandomEnumStartHere"Start Here"valueof()"Start Here"StartHere

কিভাবে আমি এটি করতে পারব?


2
আরও মন্তব্য / উত্তর পেতে "জাভা" ট্যাগ যুক্ত করুন।
জাভা 42

উত্তর:


197

আপনি এই কোড চেষ্টা করে দেখতে পারেন। যেহেতু আপনি valueOfপদ্ধতিটিকে ওভাররাইড করতে পারবেন না তাই আপনাকে একটি কাস্টম পদ্ধতি ( getEnumনীচের নমুনা কোডে) সংজ্ঞায়িত করতে হবে যা আপনার প্রয়োজনীয় মানটি দেয় এবং পরিবর্তে এই পদ্ধতিটি ব্যবহার করতে আপনার ক্লায়েন্টকে পরিবর্তন করতে পারে।

public enum RandomEnum {

    StartHere("Start Here"),
    StopHere("Stop Here");

    private String value;

    RandomEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

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

    public static RandomEnum getEnum(String value) {
        for(RandomEnum v : values())
            if(v.getValue().equalsIgnoreCase(value)) return v;
        throw new IllegalArgumentException();
    }
}

4
getEnum সংক্ষেপিত হতে পারে যদি আপনি নিম্নলিখিতগুলি করেন: v.getValue ()। সমান (মান); নাল চেক বাদ দেওয়া যেতে পারে।
rtcarlson

আপনি অলসভাবে একটি মানচিত্র তৈরি করতে এবং এটি পুনরায় ব্যবহার করতে পারেন, তবে এটি তৈরির সময় থ্রেডিংয়ের বিষয়গুলি থেকে সাবধান থাকুন।
মার্টেন বোদেউয়েস

11
এমন পরিস্থিতিতে এমন কোনও পরিস্থিতিতে কাজ করে না যেখানে আপনি ভ্যালু () পাওয়ার জন্য ওয়েলওফ () পদ্ধতির কলিং পরিবর্তন করতে পারবেন না যেমন উদাহরণস্বরূপ যখন আপনি হাইবারনেট টীকাগুলির মাধ্যমে মানগুলি মানচিত্রের জন্য নির্দিষ্ট ক্ষেত্রগুলি সংজ্ঞায়িত করেন
mmierins

জাভাতে এনামগুলি সংশোধন না করা অবধি, @ ব্যাটের আরও উপযুক্ত এবং ওও বান্ধব সমাধান রয়েছে। নাম () চূড়ান্ত হওয়া উচিত নয়।
অ্যান্ড্রু টি ফিনেল

পরিবর্তে আপনি valueOf (র্যান্ডমইনাম.ক্লাস, মান) ব্যবহার করতে পারেন;
ওয়াজটেক

22

এটি চেষ্টা করে দেখুন, তবে আমি নিশ্চিত নই যে এটি যেখানেই কাজ করবে :)

public enum MyEnum {
    A("Start There"),
    B("Start Here");

    MyEnum(String name) {
        try {
            Field fieldName = getClass().getSuperclass().getDeclaredField("name");
            fieldName.setAccessible(true);
            fieldName.set(this, name);
            fieldName.setAccessible(false);
        } catch (Exception e) {}
    }
}

18
আমি একমাত্র কেন এমন ধরণের জিনিসটিকে খারাপ দেখায়? আমি বোঝাতে চাইছি এটি দেখতে দুর্দান্ত লাগছে তবে প্রসঙ্গের সহিত কেউ এই কোডটি পড়ে না এমন সম্ভবত "WTF?" এর মতো হবে।
নিকোলাস গিলাইম

11
@ নিকোলাস গুইলিউম এটি এমন এক ধরণের কোড, যা প্রয়োগ করা হলে, কেন এটি আছে এবং প্রোগ্রামার কী সমস্যা সমাধানের চেষ্টা করছে তা ব্যাখ্যা করার জন্য মরিয়া হয়ে মন্তব্যটির প্রয়োজন হবে। :-)
ত্রি স্টারগা

9
জেনেরিক ব্যতিক্রম ধরবেন না, কারণ এটি আউট অফ মেমরি বা কিছু
ক্রুসে

2
এটি একটি ভয়ানক ধারণা। যার মধ্যে কমপক্ষে কোনও ইঙ্গিত বা পুনরুদ্ধার ছাড়াই নীরব ত্রুটির সম্ভাবনা। এছাড়াও এখন "নাম" মান এবং কোডের প্রতীকী মান (যেমন এ, বি) আলাদা are চতুর হওয়ার জন্য +2। ভয়ানক চালাক হওয়ার জন্য -200। আমি কোনও কোড পর্যালোচনা অনুমোদনের কোনও উপায় নেই।
পেডোরো

1
@pedorro এটি আপনার হিসাবে যতটা ভয়ঙ্কর তৈরি করছে তা ততটা ভয়ঙ্কর বলে মনে হচ্ছে না। যে কেউ যা বুঝতে পেরেছিল যে জাভা কমিটি যা কিছু করে তা ইঞ্জিল হিসাবে নেওয়া উচিত নয় কারণ এটি একটি কোড পর্যালোচনাতে পাস করবে। পুনরায় লেখার পরে এনাম ইউটিলিটি পদ্ধতির সমস্ত রক্ষণাবেক্ষণ করা খুব খারাপ কারণ নাম () ওভাররাইড করা যায় না। ব্যতিক্রমটি ধরা এবং এটি গিলে ফেলার পরিবর্তে একটি রানটাইম এক্সেপশন নিক্ষেপ করা উচিত এবং তারপরে এটি ঠিক আছে।
অ্যান্ড্রু টি ফিনেল 15:58

14

আপনি আপনার এনামে একটি স্ট্যাটিক ম্যাপ ব্যবহার করতে পারেন যা স্ট্রিংসকে এনাম কনস্ট্যান্টের মানচিত্র করে। এটি একটি 'getEnum' স্ট্যাটিক পদ্ধতিতে ব্যবহার করুন। আপনি যখনই এর স্ট্রিংয়ের মান থেকে একটি পেতে চান প্রতিবার এনামগুলিতে পুনরাবৃত্তি করার প্রয়োজনটি এড়িয়ে যায়।

public enum RandomEnum {

    StartHere("Start Here"),
    StopHere("Stop Here");

    private final String strVal;
    private RandomEnum(String strVal) {
        this.strVal = strVal;
    }

    public static RandomEnum getEnum(String strVal) {
        if(!strValMap.containsKey(strVal)) {
            throw new IllegalArgumentException("Unknown String Value: " + strVal);
        }
        return strValMap.get(strVal);
    }

    private static final Map<String, RandomEnum> strValMap;
    static {
        final Map<String, RandomEnum> tmpMap = Maps.newHashMap();
        for(final RandomEnum en : RandomEnum.values()) {
            tmpMap.put(en.strVal, en);
        }
        strValMap = ImmutableMap.copyOf(tmpMap);
    }

    @Override
    public String toString() {
        return strVal;
    }
}

কেবল এনাম কনস্ট্যান্টের ঘোষণার নীচে মানচিত্রের স্থির সূচনা ঘটেছিল তা নিশ্চিত করুন।

বিটিডাব্লু - যে 'ইমটুটেবল ম্যাপ' টাইপটি গুগল পেয়ারা এপিআই থেকে আসে এবং আমি অবশ্যই এটির মতো ক্ষেত্রে এটির প্রস্তাব দিই।


সম্পাদনা - মতামত অনুযায়ী:

  1. এই সমাধানটি ধরে নিয়েছে যে প্রতিটি নির্ধারিত স্ট্রিংয়ের মানটি অনন্য এবং নাল নয়। এনামের স্রষ্টা এটি নিয়ন্ত্রণ করতে পারবেন এবং স্ট্রিংটি অনন্য ও নন এনাম মানের সাথে মিল রেখে দেওয়া হবে এটি নিরাপদ সীমাবদ্ধতার মতো বলে মনে হচ্ছে।
  2. প্রশ্নে জিজ্ঞাসা করা হিসাবে আমি 'টুস্ট্রিং ()' পদ্ধতি যুক্ত করেছি

1
আমি এই উত্তরে বেশ কয়েকটি ডাউন ভোট পেয়েছি - এই উত্তরটি খারাপ কেন যে কেউ প্রসারিত করার বিষয়ে চিন্তা করে? লোকেরা কী ভাবছে আমি কেবল কৌতুহলী।
পেডোরো

এটি একরকম 'মান' এর মতো বা কোনও 'মান' সহ একাধিক এনাম ধ্রুবক রাখার দৃশ্যের জন্য ব্যর্থ হবে (যেমন RestartHere("replay"), ReplayHere("replay")PauseHere, WaitHereprivate RandomEnum() { this.strVal = null; }
এনামের

1
আপনার + ইমট্যুটেবল ম্যাপ :: অনুলিপি তৈরি করতে কোনও মিউটেবলম্যাপ তৈরি করার পরিবর্তে ইমট্যটেবল ম্যাপ.বিল্ডার ব্যবহার করা উচিত।
ব্রায়ান করেল

এটি আকর্ষণীয় দেখায় তবে এনামের কয়েকটি পৃথক মান থাকে তবে সেগুলি পুনরাবৃত্তি হতে খুব বেশি সময় লাগবে না। এনামের যদি অনেকগুলি মান থাকে তবে এটি সম্ভবত মূল্যবান।
বেন থারলি

13

একটি জাভা 8 বাস্তবায়ন সম্পর্কে কীভাবে? (নাল আপনার ডিফল্ট এনাম দ্বারা প্রতিস্থাপন করা যেতে পারে)

public static RandomEnum getEnum(String value) {
    List<RandomEnum> list = Arrays.asList(RandomEnum.values());
    return list.stream().filter(m -> m.value.equals(value)).findAny().orElse(null);
}

অথবা আপনি ব্যবহার করতে পারেন:

...findAny().orElseThrow(NotFoundException::new);

2

আমি মনে করি না যে আপনি কাজ করার জন্য মান "(এখানে শুরু করুন") পাচ্ছেন। তবে যতদূর পর্যন্ত স্পেস ... নিচে চেষ্টা করুন ...

static private enum RandomEnum {
    R("Start There"), 
    G("Start Here"); 
    String value;
    RandomEnum(String s) {
        value = s;
    }
}

System.out.println(RandomEnum.G.value);
System.out.println(RandomEnum.valueOf("G").value);

Start Here
Start Here

2

নীচে মানOf () এর একটি দুর্দান্ত জেনেরিক বিকল্প

public static RandomEnum getEnum(String value) {
  for (RandomEnum re : RandomEnum.values()) {
    if (re.description.compareTo(value) == 0) {
      return re;
    }
  }
  throw new IllegalArgumentException("Invalid RandomEnum value: " + value);
}

স্ট্রিংয়ের compareTo()চেয়ে বেশি মার্জিত ব্যবহার equals()কি?
বেটলিস্ট

কমনীয়তা কোনও সমস্যা নয় - আমি সম্মতি জানাই যে .equals()এটি ভাল কাজ করবে। আপনি চাইলে ব্যবহার ==করতে পারেন। (যদিও যুক্তিসঙ্গত কারণ হ'ল আপনার কখনই কোনও শ্রেণীর সাথে এনাম প্রতিস্থাপন করা উচিত নয়))
ব্যতিক্রম

3
স্ট্রিং তুলনার জন্য @ ইতিবাচক কখনও ব্যবহার করুন == এটি বস্তুর সমতা চেক করবে কারণ আপনার প্রয়োজন বিষয়বস্তু সমতা চেক এবং তার জন্য স্ট্রিং ক্লাসের সমান () পদ্ধতির ব্যবহার।
স্যাটিউ করুন

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