जावा में इंडेक्स से एनम वैल्यू कैसे प्राप्त करें?


96

मेरे पास जावा में एक एनुम है:

public enum Months
{
    JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
}

मैं इंडेक्स द्वारा एनम वैल्यूज को एक्सेस करना चाहता हूं, जैसे

Months(1) = JAN;
Months(2) = FEB;
...

मैं ऐसा कैसे करूंगा?


12
कंप्यूटर विज्ञान में, सूचकांक 0 से शुरू होता है, न कि 1 ;-) से
फ़्रेडओवरफ़्लो

1
क्या आप निस्चय ही यह कार्य करना चाहते हैं? आम तौर पर आपको निम्न-स्तरीय डेटा संरचनाओं को लागू करने के अलावा, अध्यादेश को नहीं छूना चाहिए (और फिर, वैकल्पिक तंत्र का उपयोग करें, जैसे कि नाम, दृढ़ता के लिए)।
टॉम हॉकिन - 12:14 बजे

आप java.util.Calendar वर्ग में भी स्थिरांक का उपयोग कर सकते थे। उन्हें जनवरी के लिए 0 - 11 नंबर दिया गया है। 12 दिसंबर से सावधान रहें क्योंकि यह अनडाइंड (चंद्र कैलेंडर के साथ कुछ करना) है। लेकिन मैं अभी उत्सुक हूं कि महीने के स्थिरांक के पहिए का फिर से आविष्कार क्यों किया जाए जो पहले से ही जेआरई में "स्टॉक" आता है?
क्रिस एल्डरिक

2FredOverflow: एग्री, मैंने गलत इंडेक्सिंग का उपयोग किया। 2 टोम हॉकिन: हां, मुझे यकीन है। मैं कुछ ढांचे के साथ डेटा को जारी रखता हूं और मुझे पूर्णांक इंडेक्स मिलता है, एनम नहीं। 2 क्रिस एल्डरिच: यह सिर्फ डमी उदाहरण है जो वास्तविक मामले से मेल नहीं खाता है।
jk_

वैसे, जावा 8 और बाद में एक Monthएनम बिल्ट-इन के साथ आता है।
तुलसी बोर्के

जवाबों:


229

इसे इस्तेमाल करे

Months.values()[index]

37
ध्यान दें कि हर बार मान सरणी की एक प्रति क्लोन करेगा, इसलिए यदि आप इसे प्रदर्शन संवेदनशील कोड के आंतरिक लूप में बुला रहे हैं तो आप एक स्थिर प्रतिलिपि बनाना और उसका उपयोग करना चाह सकते हैं।
क्रिस्टोफर बार्बर

1
मैं उलझन में हूँ, फिर मैं इसके बजाय एक सरणी का उपयोग क्यों नहीं करना चाहूंगा?
अनुदीप सामैया

@AnudeepSamaiya हो सकता है कि हम हर महीने महीनों [1] के बजाय कोड में उचित एनम कांस्टेंट (महीने। JAN) का उपयोग करना चाहते हैं।
हैरी जॉय

@Christopher Barber यहाँ "स्टेटिक कॉपी बनाने" के लिए एक-लाइनर है: public static final ArrayList<Months> ALL = new ArrayList<Month>() {{ for (Months m : Months.values()) add(m); }};तो आप तत्वों को एक्सेस कर सकते हैंMonths i = ALL.get(index)
muelleth

बस मोंटेवल्स () (क्लोन) () क्लोन का उपयोग करना आसान होगा या यदि आप इसे अपरिवर्तनीय सूची में लिपटने के लिए परिवर्तनशीलता के बारे में पागल हैं (संग्रह देखें)
क्रिस्टोफर नाई

20

यहाँ यह करने के लिए तीन तरीके हैं।

public enum Months {
    JAN(1), FEB(2), MAR(3), APR(4), MAY(5), JUN(6), JUL(7), AUG(8), SEP(9), OCT(10), NOV(11), DEC(12);


    int monthOrdinal = 0;

    Months(int ord) {
        this.monthOrdinal = ord;
    }

    public static Months byOrdinal2ndWay(int ord) {
        return Months.values()[ord-1]; // less safe
    }

    public static Months byOrdinal(int ord) {
        for (Months m : Months.values()) {
            if (m.monthOrdinal == ord) {
                return m;
            }
        }
        return null;
    }
    public static Months[] MONTHS_INDEXED = new Months[] { null, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };

}




import static junit.framework.Assert.assertEquals;

import org.junit.Test;

public class MonthsTest {

@Test
public void test_indexed_access() {
    assertEquals(Months.MONTHS_INDEXED[1], Months.JAN);
    assertEquals(Months.MONTHS_INDEXED[2], Months.FEB);

    assertEquals(Months.byOrdinal(1), Months.JAN);
    assertEquals(Months.byOrdinal(2), Months.FEB);


    assertEquals(Months.byOrdinal2ndWay(1), Months.JAN);
    assertEquals(Months.byOrdinal2ndWay(2), Months.FEB);
}

}

5
public staticउत्परिवर्तनीय (दोनों सरणी और गैर- final)। EUW। और बम IllegalArgumentExceptionवापस करने से ज्यादा समझदारी होगी null
टॉम हॉकिन -

2

मैंने बस यही कोशिश की और निम्नलिखित समाधान के साथ आया:

public enum Countries {
    TEXAS,
    FLORIDA,
    OKLAHOMA,
    KENTUCKY;

    private static Countries[] list = Countries.values();

    public static Countries getCountry(int i) {
        return list[i];
    }

    public static int listGetLastIndex() {
        return list.length - 1;
    }
}

किसी सरणी के अंदर सहेजे गए मानों का अपना वर्ग होता है, और मैं अनुक्रमांक में एनम प्राप्त करने के लिए सरणी का उपयोग करता हूं। जैसा कि ऊपर बताया गया है 0 से गिनती शुरू होती है, यदि आप चाहते हैं कि आपका सूचकांक '1' से शुरू हो तो बस इन दो तरीकों को बदल दें:

public static String getCountry(int i) {
    return list[(i - 1)];
}

public static int listGetLastIndex() {
    return list.length;
}

मेरे मुख्य के अंदर मुझे आवश्यक देश-वस्तु मिलती है

public static void main(String[] args) {
   int i = Countries.listGetLastIndex();
   Countries currCountry = Countries.getCountry(i);
}

जो इस मामले में पिछले देश के लिए करिकाउंट सेट करता है। Country.KENTUCKY।

बस याद रखें कि यह कोड ArrayOutOfBoundsException से बहुत प्रभावित है अगर आप हार्डकोड का उपयोग कर रहे हैं तो अपनी वस्तुओं को पाने के लिए संकेत देता है।


1

मुझे हाल ही में एक ही समस्या थी और हैरी जॉय द्वारा प्रदान किए गए समाधान का उपयोग किया। हालांकि यह समाधान केवल शून्य-आधारित एनुमरेशन के साथ काम करता है। मैं भी इसे बचाने पर विचार नहीं करूंगा क्योंकि यह उन अनुक्रमितों से नहीं निपटता है जो सीमा से बाहर हैं।

मेरे द्वारा उपयोग किया गया समाधान उतना सरल नहीं हो सकता है, लेकिन यह पूरी तरह से बचा हुआ है और आपके कोड के प्रदर्शन को भी बड़ी चोटों से चोट नहीं पहुंचाएगा:

public enum Example {

    UNKNOWN(0, "unknown"), ENUM1(1, "enum1"), ENUM2(2, "enum2"), ENUM3(3, "enum3");

    private static HashMap<Integer, Example> enumById = new HashMap<>();
    static {
        Arrays.stream(values()).forEach(e -> enumById.put(e.getId(), e));
    }

    public static Example getById(int id) {
        return enumById.getOrDefault(id, UNKNOWN);
    }

    private int id;
    private String description;

    private Example(int id, String description) {
        this.id = id;
        this.description= description;
    }

    public String getDescription() {
        return description;
    }

    public int getId() {
        return id;
    }
}

यदि आप सुनिश्चित हैं कि आप कभी भी अपने सूचकांक के दायरे से बाहर नहीं होंगे और आप इसका उपयोग नहीं करना चाहते हैं UNKNOWNजैसे मैंने ऊपर किया है तो आप भी कर सकते हैं:

public static Example getById(int id) {
        return enumById.get(id);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.