জাভাতে সূচক থেকে এনাম মান কীভাবে পাবেন?


97

জাভাতে আমার একটি এনাম রয়েছে:

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

আমি সূচী দ্বারা এনাম মানগুলি অ্যাক্সেস করতে চাই eg

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

কীভাবে করব?


12
কম্পিউটার সায়েন্সে সূচকগুলি 0 থেকে শুরু হয়, 1 ;-) নয়
ফ্রেডওভারফ্লো

4
তুমি কি নিশ্চিত তুমি কি চাও? সাধারণত আপনার নিম্ন-স্তরের ডেটা স্ট্রাকচার বাস্তবায়ন ব্যতীত অর্ডিনাল স্পর্শ করা উচিত নয় (এবং তারপরে, অধ্যবসায়ের জন্য নাম হিসাবে বিকল্প মেকানিজম ব্যবহার করুন)।
টম হাটিন -

আপনি জাভা.ইটি.টি.ক্যালেন্ডার ক্লাসেও কনস্ট্যান্ট ব্যবহার করতে পারতেন। জানুয়ারি - ডিসেম্বরের জন্য তাদের 0 - 11 নম্বরযুক্ত রয়েছে। 12 ডিসেম্বর অবধি সাবধান থাকুন (চন্দ্র ক্যালেন্ডারের সাথে কিছু করার জন্য)। তবে আমি শুধু কৌতূহল করছি কেন জেআরইতে ইতিমধ্যে "স্টক" আসে এমন মাসের ধ্রুবকের চাকাটি পুনরায় উদ্ভাবন করা হচ্ছে?
ক্রিস অ্যালডরিচ

2 ফ্রেড ওভারফ্লো: সম্মতি, আমি ভুল ইনডেক্সিং ব্যবহার করেছি। টম হাটিন: হ্যাঁ, আমি নিশ্চিত am আমি কিছু ফ্রেমওয়ার্কের সাথে ডেটা বজায় রাখি এবং এনাম নয়, আমি পূর্ণসংখ্যার সূচক ফিরে পাই। 2 ক্রিস অ্যালডরিচ: এটি কেবল ডামি উদাহরণ যা বাস্তবের সাথে মেলে না।
জে কে_

যাইহোক, জাভা 8 এবং পরে Monthঅন্তর্নির্মিত একটি এনামের সাথে আসে ।
বেসিল বাউর্কে

উত্তর:


234

এটা চেষ্টা কর

Months.values()[index]

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

4
আমি বিভ্রান্ত হয়ে পড়েছি, তবে কেন আমি তার পরিবর্তে একটি অ্যারে ব্যবহার করব না?
অনুদীপ সামাইয়া

@ অনুদীপসামাইয়া হতে পারে আমরা কোথাও মাস [1] এর পরিবর্তে কোডে যথাযথ এনাম কনস্ট্যান্ট (মাসস.জান) ব্যবহার করতে চাই।
হ্যারি জয়

@ ক্রিস্টোফার বারবার এখানে "স্ট্যাটিক কপি তৈরি করার" জন্য একটি লাইন রয়েছে: public static final ArrayList<Months> ALL = new ArrayList<Month>() {{ for (Months m : Months.values()) add(m); }};তারপরে আপনি উপাদানগুলি অ্যাক্সেস করতে পারবেনMonths i = ALL.get(index)
মাইল্লেথ

সহজেই মাসসভালভস ()। ক্লোন () ব্যবহার করা সহজ হয় বা যদি আপনি অপরিবর্তনীয় তালিকায় এটি মুড়ে ফেলার পরিবর্তনের বিষয়ে বিতর্কিত হন (সংগ্রহ দেখুন)
ক্রিস্টোফার বারবার

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);
}

}

4
public staticপরিবর্তনীয় (উভয় অ্যারে এবং অ- final) ইওউ। এবং IllegalArgumentExceptionএকটি nullবোমা ফিরিয়ে দেওয়ার চেয়ে অনেক বেশি অর্থবোধ করতে পারে ।
টম হাটিন -

4

আমি ঠিক একই চেষ্টা করেছি এবং নিম্নলিখিত সমাধান নিয়ে এসেছি:

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);
}

এই ক্ষেত্রে, দেশগুলি.কেনটুকি।

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


2

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

আমি যে সমাধানটি ব্যবহার করে শেষ করেছি তা এত সহজ নাও হতে পারে তবে এটি সম্পূর্ণরূপে সংরক্ষণ করে এবং আপনার কোডের কার্যকারিতা বড় এনামগুলির সাথেও আঘাত করবে না:

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