স্ট্রিং হিসাবে এনামে সমস্ত নাম পাওয়া []


97

এন এর উপাদান হিসাবে এনাম উপাদানগুলির নাম পাওয়ার সহজতম এবং / অথবা সবচেয়ে সংক্ষিপ্ততম উপায় কী String?

আমি এর দ্বারা যা বোঝাচ্ছি তা হ'ল, উদাহরণস্বরূপ, আমার কাছে নিম্নলিখিত এনাম থাকলে:

public enum State {
    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED;

    public static String[] names() {
        // ...
    }
}

names()পদ্ধতি অ্যারে ফিরে আসবে { "NEW", "RUNNABLE", "BLOCKED", "WAITING", "TIMED_WAITING", "TERMINATED" }


4
কোনও নেটিভ এনাম পদ্ধতি কেন নেই যা হুবহু এটি আমার বাইরে ... এবং মূল্য প্রাপ্তি ()
মার্কোলোপস

উত্তর:


92

যে কোনও enumশ্রেণীর জন্য এখানে এক-লাইনার রয়েছে :

public static String[] getNames(Class<? extends Enum<?>> e) {
    return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new);
}

প্রাক জাভা 8 এখনও একটি ওয়ান-লাইনার হলেও কম মার্জিত:

public static String[] getNames(Class<? extends Enum<?>> e) {
    return Arrays.toString(e.getEnumConstants()).replaceAll("^.|.$", "").split(", ");
}

যে আপনি এই মত কল করবে:

String[] names = getNames(State.class); // any other enum class will work

আপনি যদি হার্ড কোডিং এনুম শ্রেণীর জন্য সহজ কিছু চান:

public static String[] names() {
    return Arrays.toString(State.values()).replaceAll("^.|.$", "").split(", ");
}

4
কাজটি করার জন্য দ্রুততম উপায় নয়, তবে দুর্দান্ত রেজেক্স।
ceklock

4
জাভা 8 সমাধানে, কোনও পদ্ধতির সুযোগের বাইরে, পরিবর্তে e.getEnumConstants()আপনি ব্যবহার করতে পারেনYourEnumName.values()
oদো 95

4
@ Oদো 95 ব্যবহার YourEnumName.values()করে ক্লাসে একটি স্ট্যাটিক পদ্ধতি কল করছে, যা কোনও এনামের জন্য পুনরায় ব্যবহার করা যাবে না । getEnumConstants()যে কোনও এনাম ক্লাসের জন্য কাজ করে । এই পদ্ধতির সাথে ধারণাটি হ'ল এমন একটি ইউটিলিটি পদ্ধতি পুনরায় তৈরি করা যা আপনি উত্তরের শেষ লাইনের মতো কল করতে পারেন।
বোহেমিয়ান

যদি আপনি আপনার এনামের জন্য একটি কাস্টম লেবেল চান তবে আপনার এনম শ্রেণিতে টু স্ট্রিং () ওভাররাইড করুন।
ralphgabb

আপনি দয়া করে ব্যাখ্যা করতে পারেন Class<? extends Enum<?>> e?
কারমাজেডন

63

String[]নামের জন্য একটি অ্যারে তৈরি করুন এবং values()স্থিতির পদ্ধতিতে কল করুন যা সমস্ত এনাম মানগুলি দেয়, তারপরে মানগুলি পুনরাবৃত্তি করে এবং নামগুলি অ্যারে তৈরি করে।

public static String[] names() {
    State[] states = values();
    String[] names = new String[states.length];

    for (int i = 0; i < states.length; i++) {
        names[i] = states[i].name();
    }

    return names;
}

9
values()লোকাল ভেরিয়েবলে অ্যারে ক্যাশে না করে প্রতিবার নতুন অ্যারে তৈরি করে কেন 13 বার কল করুন ? এর পরিবর্তে ওভাররডেবল যা স্ট্রিং () ব্যবহার করবেন name()?
জেবি নিজেট

@ জেবিনিজেট হিহহ, আমি আমার আইডিইতে চেষ্টা করেছি এবং আমার অনুমানের সাথে একটি স্টেট অ্যারে তৈরি করতে অলসতার উপায়টিও হয়েছে, যাইহোক, এখনই এটি এডিট করেছেন :)
পার্মজেনারর

4
আপনি এখনও নামগুলি ফিরিয়ে দিচ্ছেন না, তবে টসস্ট্রিং () মানগুলি।
জেবি নিজেট

@ জেবিনিজেট হুম, টিবিএইচ, আমি সত্যিই জানি না যে name()এখন পর্যন্ত একটি পদ্ধতি ছিল । আমাকে কতটা বোকা: পি আমাকে জানানোর জন্য ধন্যবাদ :)
PermGenError

4
আমি এই উত্তরটি গ্রহণ করেছি, তবে আমি এমন একটি সম্পাদনা জমা দিয়েছি যা কোডের উন্নতি করে যাতে এটি পড়া সহজ হয়।
কনস্টান্টিন

15

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

EnumUtils.getEnumList(State.class)

যদিও এটি একটি তালিকা দেয়, আপনি সহজেই তালিকাটি রূপান্তর করতে পারেন list.toArray()


6
EnumUtils.getEnumList(enumClass)স্ট্রিংস নয়, এনাম মানগুলি প্রদান করে। আপনি ব্যবহার করতে পারেন EnumUtils.getEnumMap(enumClass).keySet(), তবে ক্রমটি আলাদা হতে পারে।
ড্যান হালবার্ট

13

আপনি যদি জাভা 8 ব্যবহার করতে পারেন তবে এটি দুর্দান্তভাবে কাজ করে (ইউরার পরামর্শের বিকল্প, আরও দক্ষ):

public static String[] names() {
    return Stream.of(State.values()).map(State::name).toArray(String[]::new);
}

9

জাভা 8 সহ:

Arrays.stream(MyEnum.values()).map(Enum::name)
                    .collect(Collectors.toList()).toArray();

4
এটি সম্ভবত কাজ করার সময়, এই বাস্তবায়নটি বেশ অদক্ষ, প্রথমে একটি অ্যারেলিস্ট তৈরি করে, সমস্ত উপাদান যুক্ত করে, তারপরে একটি অ্যারে তৈরি করে এবং সমস্ত কিছু অনুলিপি করে।
ড্যানিয়েল বিমসচাস

যে কোনও সময় শীঘ্রই "প্রত্যেকে" সর্বাধিক প্রাথমিক ক্রিয়াকলাপ সম্পাদন করতে স্ট্রিম ব্যবহার করবে ... এবং এটি খুব ভাল ধারণা নয়।
মার্কোলপস

এনামগুলিতে উপাদানের সংখ্যা সাধারণত কম হলেও এই বিষয়টি বিবেচনা করে আমি মনে করি যে অনেক ব্যবহারের ক্ষেত্রে ইউুরার সমাধানটি ঠিক থাকবে। স্বাভাবিকভাবেই, এটি নির্দিষ্ট পরিস্থিতির উপর নির্ভর করবে ...
স্টেফান.ম

6

আমি এটি লিখতে হবে

public static String[] names() {

    java.util.LinkedList<String> list = new LinkedList<String>();
    for (State s : State.values()) {
        list.add(s.name());
    }

    return list.toArray(new String[list.size()]);
}

4

অন্য উপায়:

প্রথমটি

Arrays.asList(FieldType.values())
            .stream()
            .map(f -> f.toString())
            .toArray(String[]::new);

অন্য মাধ্যম

Stream.of(FieldType.values()).map(f -> f.toString()).toArray(String[]::new);

4
ইন এই ক্ষেত্রে toString()কাজ করে, তবে সাধারণভাবে ক্ষেত্রে এটি যায় না, কারণ toString()ওভাররাইড করা যেতে হতে পারে। স্ট্রিং হিসাবে .name()উদাহরণের নামটি নির্ভরযোগ্যভাবে পেতে ব্যবহার করুন ।
বোহেমিয়ান

3

এরকম কিছু কাজ করবে:

public static String[] names() {
  String[] names = new String[values().length];
  int index = 0;

  for (State state : values()) {
    names[index++] = state.name();
  }

  return names;
}

ডকুমেন্টেশনটি বেশিরভাগ ক্ষেত্রে toString()পরিবর্তে ব্যবহারের পরামর্শname() দেয় তবে আপনি এখানে স্পষ্টভাবে নামটি চেয়েছিলেন।


4
যদিও এটি বিশেষভাবে গুরুত্বপূর্ণ নয়, লুপের জন্য নিয়মিত এই পরিস্থিতিতে ফোরচ লুপের চেয়ে আরও ভাল পারফরম্যান্স সরবরাহ করে। প্লাস, values()দুবার বলা হয় যখন এটি কেবল একবার কল করা প্রয়োজন।
এফটিহম্পসন

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

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

4
@ ageষি 88 আমি লুপগুলির জন্য উল্লেখ করছিলাম যেখানে আপনি একটি সংখ্যাসূচক সূচক ব্যবহার করে উপাদানগুলি পুনরুদ্ধার করেন যা আপনি প্রতিটি চক্রের বৃদ্ধি করেন। উদাহরণস্বরূপ: for (int i = 0; i < a.length; i++) /* do stuff */;এই ক্ষেত্রে, লুপ প্রতিটি জন্য- হয় , আসলে, আরও দক্ষ। বিষয়টি সম্পর্কে একটি দ্রুত এসও অনুসন্ধান আমাদের এটি দেয়: স্ট্যাকওভারফ্লো
কনস্ট্যান্টিন

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

2

স্ট্রিংগুলির হেরফের সহ আমার সমাধান (দ্রুত নয়, তবে কমপ্যাক্ট):

public enum State {
    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED;

    public static String[] names() {
        String valuesStr = Arrays.toString(State.values());
        return valuesStr.substring(1, valuesStr.length()-1).replace(" ", "").split(",");
    }
}

এবং জাভা 7 অনুগত!
কুম্ভ শক্তি

2

সাধারণ উপায় (পাং উদ্দেশ্য):

String[] myStringArray=new String[EMyEnum.values().length];
for(EMyEnum e:EMyEnum.values())myStringArray[e.ordinal()]=e.toString();

1

আমি এটি এইভাবে করব (তবে আমি সম্ভবত একটি অ্যারের পরিবর্তে নামগুলি একটি অবিশ্বাস্য সেট হিসাবে তৈরি করব):

import java.util.Arrays;
enum State {
    NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;
    public static final String[] names=new String[values().length];
    static {
        State[] values=values();
        for(int i=0;i<values.length;i++)
            names[i]=values[i].name();
    }
}
public class So13783295 {
    public static void main(String[] args) {
        System.out.println(Arrays.asList(State.names));
    }
}

আমি বারবার এনামের নাম লেখার প্রয়োজন হলে আমি এ জাতীয় কিছু করব, তবে যেহেতু names()পদ্ধতিটি কেবল অল্প পরিমাণে বলা হয়, তাই আমি মনে করি যে ঘটনাস্থলে একটি অ্যারে তৈরি করা ভাল।
কনস্টান্টিন

1

আমার একই চাহিদা রয়েছে এবং একটি জেনেরিক পদ্ধতি (একটি অ্যারে ইউটিলস শ্রেণীর অভ্যন্তরে) ব্যবহার করুন:

public static <T> String[] toStringArray(T[] array) {
    String[] result=new String[array.length];
    for(int i=0; i<array.length; i++){
        result[i]=array[i].toString();
    }
    return result;
}

এবং এনামের ভিতরে কেবল একটি স্ট্যাটিক সংজ্ঞায়িত করুন ...

public static final String[] NAMES = ArrayUtils.toStringArray(values());

জাভা এনামগুলি সত্যই একটি নাম () মিস করে এবং (সূচীকরণ) পদ্ধতিগুলি পায়, তারা সত্যই সহায়ক।


1

আমি @ বোহেমিয়ান এর সমাধান সম্পর্কে কিছুটা পরীক্ষা করেছি। পরিবর্তে নিষ্পাপ লুপ ব্যবহার করার সময় পারফরম্যান্স আরও ভাল।

public static <T extends Enum<?>> String[] getEnumNames(Class<T> inEnumClass){
    T [] values = inEnumClass.getEnumConstants();
    int len = values.length;
    String[] names = new String[len];
    for(int i=0;i<values.length;i++){
        names[i] = values[i].name();
    }
    return names;
}

//Bohemian's solution
public static String[] getNames(Class<? extends Enum<?>> e) {
    return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new);
}

পারফরম্যান্স সম্পর্কে আপনার পরিসংখ্যান দেওয়া উচিত, তারপরে পারফরম্যান্স হ্রাস তাৎপর্যপূর্ণ কিনা তা লোকেরা তাদের পক্ষে বিচার করতে পারে। আমি অনুমান করি যে এনামের জন্য বেশিরভাগ মানুষের 100+ বা 1000+ মান থাকবে না।
রুনি লিলিমেটস


1

গৃহীত উত্তরের সাথে খুব সমান, তবে যেহেতু আমি এনামসেট সম্পর্কে শিখেছি, আমি সাহায্য করতে পারি না তবে এটি সর্বত্র ব্যবহার করতে পারি। সুতরাং একটি ক্ষুদ্রতর আরও সংক্ষিপ্তসার জন্য (জাভা 8) উত্তর:

public static String[] getNames(Class<? extends Enum<?>> e) {
  return EnumSet.allOf(e).stream().map(Enum::name).toArray(String[]::new);
}

0

আপনি যদি সবচেয়ে কম চান তবে চেষ্টা করতে পারেন

public static String[] names() {
    String test = Arrays.toString(values());
    return text.substring(1, text.length()-1).split(", ");
}

সংক্ষিপ্ততম নয় :) ওয়ান-লাইনারের জন্য আমার উত্তর দেখুন (যা এখনও কেবল vales()একবারই প্রার্থনা করে )
বোহেমিয়ান

0

কেবল একটি চিন্তাধারা: সম্ভবত আপনাকে এনমের মানগুলি স্ট্রিংগুলির অ্যারে হিসাবে ফেরত দেওয়ার জন্য কোনও পদ্ধতি তৈরি করার দরকার নেই।

আপনার স্ট্রিংগুলির অ্যারে দরকার কেন? আপনার যদি কখনও এটির প্রয়োজন হয় তবে আপনাকে কেবল তখন মানগুলি রূপান্তর করতে হবে।

উদাহরণ:

for (State value:values()) {
    System.out.println(value); // Just print it.
}

for (State value:values()) {
    String x = value.toString(); // Just iterate and do something with x.
}

// If you just need to print the values:
System.out.println(Arrays.toString(State.values()));

0

জাভা 7 বা তার আগে এর অন্য উপায়টি হ'ল পেয়ারা ব্যবহার করা:

public static String[] names() {
    return FluentIterable.from(values()).transform(Enum::name).toArray(String.class);
}

0

এটা চেষ্টা কর:

public static String[] vratAtributy() {
    String[] atributy = new String[values().length];
    for(int index = 0; index < atributy.length; index++) {
        atributy[index] = values()[index].toString();
    }
    return atributy;
}

0

আপনি স্ট্রিংগুলির তালিকাতে এনাম মান রাখতে পারেন এবং অ্যারেতে রূপান্তর করতে পারেন:

    List<String> stateList = new ArrayList<>();

            for (State state: State.values()) {
                stateList.add(state.toString());
            }

    String[] stateArray = new String[stateList.size()];
    stateArray = stateList.toArray(stateArray);

0

সহজতম পথ:

Category[] category = Category.values();
for (int i = 0; i < cat.length; i++) {
     System.out.println(i  + " - " + category[i]);
}

যেখানে বিভাগের Enumনাম

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