স্ট্রিং আক্ষরিক হিসাবে এনাম মানগুলি ব্যবহার করা


389

স্ট্রিং আক্ষরিক হিসাবে এনামে সঞ্চিত মানগুলি ব্যবহার করার সর্বোত্তম উপায় কী? উদাহরণ স্বরূপ:

public enum Modes {
    some-really-long-string,
    mode1,
    mode2,
    mode3
}

তারপরে আমি Mode.mode1এর স্ট্রিং প্রতিনিধিত্ব হিসাবে ফেরত দিতে ব্যবহার করতে পারি mode1। কল না করেই থাকি Mode.mode1.toString()

উত্তর:


646

আপনি পারবেন না। আমি মনে করি আপনার কাছে এখানে চারটি বিকল্প রয়েছে। চারটিই একটি সমাধানের প্রস্তাব দেয় তবে কিছুটা ভিন্ন পদ্ধতির সাথে ...

বিকল্প এক: একটি enum উপর অন্তর্নির্মিত ব্যবহার করুন name()। আপনার কোনও বিশেষ নামকরণের বিন্যাসের প্রয়োজন না হলে এটি পুরোপুরি ঠিক fine

    String name = Modes.mode1.name(); // Returns the name of this enum constant, exactly as declared in its enum declaration.

বিকল্প দুটি: আপনি যদি আরও নিয়ন্ত্রণ চান তবে আপনার এনামগুলিতে ওভাররাইডিং বৈশিষ্ট্য যুক্ত করুন

public enum Modes {
    mode1 ("Fancy Mode 1"),
    mode2 ("Fancy Mode 2"),
    mode3 ("Fancy Mode 3");

    private final String name;       

    private Modes(String s) {
        name = s;
    }

    public boolean equalsName(String otherName) {
        // (otherName == null) check is not needed because name.equals(null) returns false 
        return name.equals(otherName);
    }

    public String toString() {
       return this.name;
    }
}

বিকল্প তিনটি: এনামগুলির পরিবর্তে স্ট্যাটিক ফাইনাল ব্যবহার করুন:

public final class Modes {

    public static final String MODE_1 = "Fancy Mode 1";
    public static final String MODE_2 = "Fancy Mode 2";
    public static final String MODE_3 = "Fancy Mode 3";

    private Modes() { }
}

বিকল্প চারটি: ইন্টারফেসের প্রতিটি ক্ষেত্র সর্বজনীন, স্থির এবং চূড়ান্ত:

public interface Modes {

    String MODE_1 = "Fancy Mode 1";
    String MODE_2 = "Fancy Mode 2";
    String MODE_3 = "Fancy Mode 3";  
}

46
এই উত্তরটি আসলে ভুল: আপনি যেমন কল করতে পারেন .name()দেখুন: stackoverflow.com/a/6667365/887836
অ্যালেক্স

3
@ kato2 সঠিক নয়। .Name () পদ্ধতিটি স্বয়ংক্রিয়ভাবে সংকলক দ্বারা তৈরি করা হয়েছে
শন প্যাট্রিক ফ্লয়েড

10
জাভাডোক: স্ট্রিং java.lang.Enum.name () এই এনামের ধ্রুবকের নাম ঠিক যেমন তার এনাম ঘোষণায় ঘোষিত হয়েছে তা ফিরিয়ে দেয়। বেশিরভাগ প্রোগ্রামারদের এটিকে পছন্দ হিসাবে টসস্ট্রিং পদ্ধতি ব্যবহার করা উচিত, কারণ টসস্ট্রিং পদ্ধতিটি আরও ব্যবহারকারী-বান্ধব নামটি ফিরে আসতে পারে। এই পদ্ধতিটি বিশেষত বিশেষ পরিস্থিতিতে ব্যবহারের জন্য ডিজাইন করা হয়েছে যেখানে নির্ভুলতা সঠিক নাম পাওয়ার উপর নির্ভর করে, যা প্রকাশ থেকে প্রকাশের ক্ষেত্রে আলাদা হয় না। রিটার্নস: এই
এনাম

@ রায়ান স্টুয়ার্টের অ্যাজারের জন্য কম কোড এবং কম কোড == বাগের কম সম্ভাবনার প্রয়োজন আছে
এরিক

4
ধ্রুবকগুলি ধরে রাখতে ইন্টারফেস ব্যবহার করবেন না: কার্যকর জাভা (তৃতীয় সংস্করণ) "শুধুমাত্র ধরণের সংজ্ঞা দেওয়ার জন্য ইন্টারফেস ব্যবহার করার" পরামর্শ দেয় (আইটেম 22)।
অলিভিয়ার গ্রাগোয়ার

481

প্রতিটি এনামের একটি নাম () এবং একটি মানOf (স্ট্রিং) পদ্ধতি উভয়ই থাকে। পূর্ববর্তী এনামের স্ট্রিংয়ের নাম দেয় এবং পরবর্তীটি এনামকে মান দেয় যার নাম স্ট্রিং। এটি কি আপনি যা খুঁজছেন এর মতো?

String name = Modes.mode1.name();
Modes mode = Modes.valueOf(name);

এনামে নিজেই স্ট্যাটিক মান (ক্লাস, স্ট্রিং) রয়েছে, যাতে আপনি এটি ব্যবহার করতে পারেন

Modes mode = Enum.valueOf(Modes.class, name);

50
এই উত্তর দেওয়া উচিত! এ ("এ") এর মতো কিছু ব্যবহার করা ত্রুটির উত্স হতে পারে এবং এটি নির্বোধ অতিরিক্ত কাজ!
ফিরজেন

12
@ ফিরজেন না যদি স্ট্রিং মানকে ফাঁকা জায়গা বা হাইফেন থাকতে দেওয়া হয় তবে এটিই এর ক্ষেত্রে some-really-long-string
সজ্জিত

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

আমি স্ট্রিং রূপান্তর নিশ্চিত করার জন্য ম্যাকিয়ংয়ের সাথে একটি লিঙ্ক যুক্ত করতে চেয়েছিলাম যারা এই valueOf(String)পদ্ধতিটি ব্যবহার করে combination toUpperCase(Locale)
অজানা আইড

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

79

আপনি toString()প্রতিটি এনাম মানের জন্য পদ্ধতিটি ওভাররাইড করতে পারেন ।

উদাহরণ:

public enum Country {

  DE {
    @Override
    public String toString() {
      return "Germany";
    }
  },
  IT {
    @Override
    public String toString() {
      return "Italy";
    }
  },
  US {
    @Override
    public String toString() {
      return "United States";
    }
  }

}

ব্যবহার:

public static void main(String[] args) {
  System.out.println(Country.DE); // Germany
  System.out.println(Country.IT); // Italy
  System.out.println(Country.US); // United States
}

2
আমি এই পছন্দ। আরও কার্যকারিতা যেমন একটি মান হিসাবে ক্লাস হিসাবে ব্যবহার না করার কারণ নেই যেমন সমস্ত মানগুলির তালিকা পেতে, প্রতিটি ধরণের স্ট্রিং ইত্যাদি পাওয়া যায়
ডায়গোসাসউ

8
কুরুচিপূর্ণ এবং পুনরায় ব্যবহারযোগ্য নয়। দেশের জন্য কনস্ট্রাক্টর হিসাবে একটি স্ট্রিং মান প্রদান করা এবং তারপরে এনামের জন্য টসস্ট্রিং () পদ্ধতিটি ওভাররাইড করা আরও অনেক ভাল।
গ্রেগ 7gkb

4
আপনার পক্ষে যখন একটি বিশাল পরিমাণ গণনা করা হয় এবং কেবল এক বা দু'জন সদস্যের জন্য কী প্রিন্ট করা হয় সেগুলি ওভাররাইড করতে চান এটি একটি ভাল কৌশল।
ডোনাল ফেলো

3
এটি মোটেও স্কেল করে না। এটি করবেন না।
sebnukem

1
এটি আমার কাছে উপলব্ধি করে
হানজলো

35

বেনি নিউজবাউয়ার যেমন উল্লেখ করেছেন, আপনি টস্ট্রিং () টি ওভাররাইট করতে পারেন। তবে পরিবর্তে প্রতিটি এনাম ফিল্ডের জন্য ট্যাস্ট্রিংটি ওভাররাইট করা আমি এর মতো আরও কিছু পছন্দ করি:

public enum Country{
    SPAIN("España"),
    ITALY("Italia"),
    PORTUGAL("Portugal");


    private String value;

    Country(final String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

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

আপনি সমস্ত ক্ষেত্র পুনরুদ্ধার করতে, সেগুলি মুদ্রণের জন্য একটি স্থিতিশীল পদ্ধতি যুক্ত করতে পারেন, ইত্যাদি প্রতিটি এনাম আইটেমের সাথে যুক্ত স্ট্রিংটি পেতে কেবল getValue কল করুন



21
public enum Modes {
  MODE1("Mode1"),
  MODE2("Mode2"),
  MODE3("Mode3");

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

আপনি এনাম থেকে স্ট্রিং হিসাবে মান পেতে যেখানেই নীচের মতো কল করতে পারেন।

Modes.MODE1.getvalue();

এটি স্ট্রিং হিসাবে "মোড 1" ফিরিয়ে দেবে।


6

আপনি ব্যবহার করতে পারেন Mode.mode1.name()তবে আপনার প্রায়শই এটি করার প্রয়োজন হয় না।

Mode mode =
System.out.println("The mode is "+mode);

6
এটি লক্ষণীয় যে + অপারেটর এনামে টু স্ট্রিং () নামাবে, এবং নাম নয়) will এবং টস্ট্রিং () নাম
বাদে

1
উভয় name()এবং toString()ওভাররাইড করা যেতে পারে, কিন্তু আশা করছি এই কোড পড়া থেকে পরিষ্কার হতে হবে enumএই ঘটছে।
পিটার লরে

9
নং নাম () চূড়ান্ত, এবং সর্বদা এনামের ঘোষণাপত্রে ঘোষিত এনামের নাম ফিরিয়ে দেয়।
জেবি নিজত

1
@ জেবি নিজেট, আপনি ঠিক বলেছেন। name()হয় final। আমাকে সংশোধন করার জন্য আপনাকে ধন্যবাদ। :)
পিটার লরে

6

যতদূর আমি জানি, নামটি পাওয়ার একমাত্র উপায় হবে

Mode.mode1.name();

আপনার যদি সত্যিই এটির প্রয়োজন হয় তবে আপনি এটি করতে পারেন:

public enum Modes {
    mode1 ("Mode1"),
    mode2 ("Mode2"),
    mode3 ("Mode3");

    private String name;       

    private Modes(String s) {
        name = s;
    }
}

1
তবে এই ক্ষেত্রে, Mode.mode1এখনও টাইপ হয় না String
ল্যারি

হ্যাঁ সঠিক. আপনার একটি getName () পদ্ধতি দরকার, যা ধরণের উদ্দেশ্যকে হারাতে পারে, তাই না, আপনি এটি করতে পারবেন না।
জেক রুসেল

"নাম" খারাপ ক্ষেত্রের নাম, এটি এনামের স্ট্যান্ডার্ড ক্ষেত্র।
ওওফ

6

আমার এনামগুলির জন্য আমি তাদের প্রত্যেককে 1 টি স্ট্রিং দিয়ে বরাদ্দ দেওয়ার কথা ভাবতে পছন্দ করি না। এইভাবে আমি এনামগুলিতে টসস্ট্রিং () পদ্ধতি প্রয়োগ করি।

enum Animal
{
    DOG, CAT, BIRD;
    public String toString(){
        switch (this) {
            case DOG: return "Dog";
            case CAT: return "Cat";
            case BIRD: return "Bird";
        }
        return null;
    }
}

1
রানটাইম ব্যতিক্রম নিক্ষেপ করা নাল ফেরার পরিবর্তে ভাল কারণ এটি অ্যাক্সেসযোগ্য কোড হওয়া উচিত?
ভাড়া

returnঅপ্রয়োজনীয় কারণ সব enums সঙ্গে enums উপর সুইচ সসীম হয়।
ড্যানন

5

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

""+ Modes.mode1

আমি এতে 100% নিশ্চিত নই তবে যতদূর আমার জ্ঞান যায় এই castালাই প্রয়োজনীয় নয়, তাই না? অন্য ভেরিয়েবলের সাথে একটি খালি স্ট্রিং সংযোগ দেওয়ার জন্য স্বয়ংক্রিয়ভাবে কোনও রূপান্তরের জন্য কল করা উচিত, বা এই নিয়মের কোনও ব্যতিক্রম আছে?
অজানা আইডি

1
আপনি ঠিক বলেছেন, সঠিক সংস্করণটি হওয়া উচিত "" + Modes.mode1। আমি উত্তরটি ঠিক করেছি
বাডি

ইবির উত্তরটি অজগর প্রতিরক্ষা স্মরণ করিয়ে দিয়েও উপকৃত হয় ''.join()
অ্যানথ্রপিক অ্যান্ড্রয়েড

5

আপনার সমস্যার সমাধান!

import java.util.HashMap;
import java.util.Map;

public enum MapEnumSample {
    Mustang("One of the fastest cars in the world!"), 
    Mercedes("One of the most beautiful cars in the world!"), 
    Ferrari("Ferrari or Mercedes, which one is the best?");

    private final String description;
    private static Map<String, String> enumMap;

    private MapEnumSample(String description) {
        this.description = description;
    }

    public String getEnumValue() {
        return description;
    }

    public static String getEnumKey(String name) {
        if (enumMap == null) {
            initializeMap();
        }
        return enumMap.get(name);
    }

    private static Map<String, String> initializeMap() {
        enumMap = new HashMap<String, String>();
        for (MapEnumSample access : MapEnumSample.values()) {
            enumMap.put(access.getEnumValue(), access.toString());
        }
        return enumMap;
    }

    public static void main(String[] args) {

        // getting value from Description
        System.out.println(MapEnumSample.getEnumKey("One of the fastest cars in the world!"));

        // getting value from Constant
        System.out.println(MapEnumSample.Mustang.getEnumValue());

        System.out.println(MapEnumSample.getEnumKey("One of the most beautiful cars in the world!"));
        System.out.println(MapEnumSample.Mercedes.getEnumValue());

        // doesnt exist in Enum
        System.out.println("Mustang or Mercedes, which one is the best?");
        System.out.println(MapEnumSample.getEnumKey("Mustang or Mercedes, which one is the best?") == null ? "I don't know!" : "I believe that "
                + MapEnumSample.getEnumKey("Ferrari or Mustang, which one is the best?") + " is the best!.");

        // exists in Enum
        System.out.println("Ferrari or Mercedes, wich one is the best?");
        System.out.println(MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") == null ? "I don't know!" : "I believe that "
                + MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") + " is the best!");

    }
}

দেখে মনে হচ্ছে ওপি-র সমস্যাটি 4 বছর আগে সমাধান হয়ে গেছে তবে স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম :)
টিডিজি

1
ধন্যবাদ, কেবল আমার মতো কাউকে সাহায্য করার জন্য, পুরাতন সমস্যার আরও উদ্দেশ্যমূলক উত্তর অনুসন্ধান করার জন্য :)
রেনান গাল্ডিনো দা সিলভা

3

এনুম কিছুটা বিশেষ শ্রেণি। এনামগুলি অতিরিক্ত ক্ষেত্র সঞ্চয় করতে পারে, পদ্ধতিগুলি বাস্তবায়ন করতে পারে ইত্যাদি উদাহরণস্বরূপ

public enum Modes {
    mode1('a'),
    mode2('b'),
    mode3('c'),
    ;
    char c;

    private Modes(char c) {
        this.c = c;
    }
    public char character() {
        return c;
    }
}

এখন আপনি বলতে পারেন:

System.out.println(Modes.mode1.character())

এবং আউটপুট দেখুন: a


3
package com.common.test;

public  enum Days {


    monday(1,"Monday"),tuesday(2,"Tuesday"),wednesday(3,"Wednesday"),
    thrusday(4,"Thrusday"),friday(5,"Friday"),saturday(6,"Saturday"),sunday(7,"Sunday");

    private int id;
    private String desc;


    Days(int id,String desc){
        this.id=id;
        this.desc=desc;
    }

    public static String getDay(int id){

        for (Days day : Days.values()) {
            if (day.getId() == id) {
                return day.getDesc();
            }
        }
        return null;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }



};

1
আপনি কীভাবে এটি সমস্যার সমাধান করবে তা ব্যাখ্যা করতে পারেন?
ফানি

আপনি এই এনামটি এই লাইনটি ব্যবহার করে যে কোনও জায়গায় কল করতে পারেন: আইডি = 1; স্ট্রিং ডেনেম = Days.getDay (আইডি); , এখানে আইডি পাস। এটি সেই

2

এই পদ্ধতিটি যে কোনওটির সাথে কাজ করা উচিত enum:

public enum MyEnum {
    VALUE1,
    VALUE2,
    VALUE3;

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

    public static DataType forValue(int value) {
        return values()[value];
    }

    public String toString() {
        return forValue(getValue()).name();
    }
}

2
public enum Environment
{
    PROD("https://prod.domain.com:1088/"),
    SIT("https://sit.domain.com:2019/"),
    CIT("https://cit.domain.com:8080/"),
    DEV("https://dev.domain.com:21323/");

    private String url;

    Environment(String envUrl) {
        this.url = envUrl;
    }

    public String getUrl() {
        return url;
    }
}

String prodUrl = Environment.PROD.getUrl();

এটি মুদ্রণ করবে:

https://prod.domain.com:1088/

এনাম স্ট্রিং ধ্রুবকগুলির জন্য এই নকশা বেশিরভাগ ক্ষেত্রে কাজ করে।


0

অনেক চেষ্টা করার পরেও আমি এই সমাধানটি নিয়ে এসেছি

public static enum Operation {

    Addition, Subtraction, Multiplication, Division,;

    public String getUserFriendlyString() {
        if (this==Addition) {
            return " + ";
        } else if (this==Subtraction) {
            return " - ";
        } else if (this==Multiplication) {
            return " * ";
        } else if (this==Division) {
            return " / ";
        }
        return "undefined";
       }
}

0

আপনি এটি চেষ্টা করতে পারেন:

public enum Modes {
    some-really-long-string,
    mode1,
    mode2,
    mode3;

    public String toString(){
        switch(this) {
            case some-really-long-string:
                return "some-really-long-string";
            case mode2:
                return "mode2";
            default: return "undefined";
        }
    }

}


0

টাইপ ত্রুটি প্রতিরোধের জন্য আমি এটি দেখতে পেলাম যে এটি আরও সহজ:

public enum Modes {
    some-really-long-string,
    mode1,
    mode2,
    mode3;

    String str;

    Modes(){
        this.str = super.name();
    }

    @Override
    @NonNull
    public String toString() {
        return str;
    }

তবে - এটি যখন লগ / প্রিন্টলনে আপনি যখন স্ট্রিং ব্যবহার করতে বা যখন জাভা স্বয়ংক্রিয়ভাবে টস্ট্রিং () পদ্ধতিটি সঙ্কলন করতে পারে তখন এটি কার্যকর হতে পারে তবে এই জাতীয় কোড লাইনে ->

// sample method that require (string,value)
intent.putExtra(Modes.mode1 ,shareElement.getMode()); // java error
// first argument enum does not return value

উপরে উল্লিখিত হিসাবে পরিবর্তে আপনি এখনও enum প্রসারিত এবং .name() এই ক্ষেত্রে যেমন ব্যবহার করতে হবে :

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