নীচের এনামটি দিয়ে জাভাতে কোনও এনম টু প্রবেশের সঠিক উপায় কী?
public enum MyEnum
{
EnumValue1,
EnumValue2
}
MyEnum enumValue = (MyEnum) x; //Doesn't work???
নীচের এনামটি দিয়ে জাভাতে কোনও এনম টু প্রবেশের সঠিক উপায় কী?
public enum MyEnum
{
EnumValue1,
EnumValue2
}
MyEnum enumValue = (MyEnum) x; //Doesn't work???
উত্তর:
MyEnum.values()[x]
যেখানে x
অবশ্যই হবে তা চেষ্টা করুন 0
বা 1
সেই এনামের জন্য একটি বৈধ অর্ডিনাল।
নোট করুন যে জাভা এনামগুলিতে প্রকৃতপক্ষে ক্লাস (এবং এনাম মানগুলি অবজেক্টস হিসাবে থাকে) এবং সুতরাং আপনি একটি এনাম int
বা একটি এমনকি কাস্ট করতে পারবেন না Integer
।
MyEnum.values()
এটি ব্যয়বহুল হিসাবে ক্যাশে করতে চাইতে পারেন । অর্থ্যাৎ আপনি যদি এটি কয়েকবার কল করেন।
MyEnum.values()[x]
একটি ব্যয়বহুল অপারেশন। পারফরম্যান্স যদি উদ্বেগের বিষয় হয় তবে আপনি এটির মতো কিছু করতে চাইতে পারেন:
public enum MyEnum {
EnumValue1,
EnumValue2;
public static MyEnum fromInteger(int x) {
switch(x) {
case 0:
return EnumValue1;
case 1:
return EnumValue2;
}
return null;
}
}
MyEnum.values()[x]
একটি ব্যয়বহুল অপারেশন হিসাবে বিবেচনা করছেন তা ব্যাখ্যা করতে পারেন । এটি বিশদে কীভাবে কাজ করে তা আমি জানি না, তবে আমার কাছে মনে হচ্ছে অ্যারেতে কোনও উপাদান অ্যাক্সেস করা কোনও বড় বিষয় হবে না, ওরফে ধ্রুবক সময়। অ্যারেটি বানাতে হলে এটি ও (এন) সময় নেয় যা আপনার সমাধানের মতো একই চলমান সময়।
values()
প্রতিবার একটি নতুন অ্যারে জেনারেট হয়েছে, কারণ অ্যারেগুলি পারস্পরিক পরিবর্তনযোগ্য তাই একাধিকবার একইরকম ফিরে আসা নিরাপদ হবে না। স্যুইচ স্টেটমেন্টগুলি অগত্যা ও (এন) নয়, সেগুলি টেবিলগুলি লাফাতে সংকলিত হতে পারে। সুতরাং লরেনজোর দাবিগুলি ন্যায়সঙ্গত বলে মনে হচ্ছে।
myEnum = myEnumValues[i]
তবুও এনামের i
আইটেমটি কোনও পরিবর্তন ছাড়াই ফিরিয়ে দেবেন ।
আপনি যদি নিজের পূর্ণসংখ্যার মান দিতে চান তবে নীচের মতো কাঠামো ব্যবহার করতে পারেন
public enum A
{
B(0),
C(10),
None(11);
int id;
private A(int i){id = i;}
public int GetID(){return id;}
public boolean IsEmpty(){return this.equals(A.None);}
public boolean Compare(int i){return id == i;}
public static A GetValue(int _id)
{
A[] As = A.values();
for(int i = 0; i < As.length; i++)
{
if(As[i].Compare(_id))
return As[i];
}
return A.None;
}
}
আপনি এই মত চেষ্টা করতে পারেন।
এলিমেন্ট আইডি সহ ক্লাস তৈরি করুন।
public Enum MyEnum {
THIS(5),
THAT(16),
THE_OTHER(35);
private int id; // Could be other data type besides int
private MyEnum(int id) {
this.id = id;
}
public static MyEnum fromId(int id) {
for (MyEnum type : values()) {
if (type.getId() == id) {
return type;
}
}
return null;
}
}
এখন int হিসাবে আইডি ব্যবহার করে এই এনামটি আনুন।
MyEnum myEnum = MyEnum.fromId(5);
আমি মানগুলি ক্যাশে করি এবং একটি সাধারণ স্ট্যাটিক অ্যাক্সেস পদ্ধতি তৈরি করি:
public static enum EnumAttributeType {
ENUM_1,
ENUM_2;
private static EnumAttributeType[] values = null;
public static EnumAttributeType fromInt(int i) {
if(EnumAttributeType.values == null) {
EnumAttributeType.values = EnumAttributeType.values();
}
return EnumAttributeType.values[i];
}
}
values
পদ্ধতির মতো একই নাম না দেন তবে এটি কম বিভ্রান্তিকর values()
। আমি cachedValues
মাঠের নাম ব্যবহার করি ।
জাভা এনামগুলিতে সি এন ++-তে একই ধরণের এনাম-টু-ইন ম্যাপিং নেই।
এটি বলেছিল যে সমস্ত এনামের একটি values
পদ্ধতি রয়েছে যা সম্ভব এনুম মানগুলির একটি অ্যারে প্রদান করে
MyEnum enumValue = MyEnum.values()[x];
কাজ করা উচিত. এটি কিছুটা বাজে এবং সম্ভবত সম্ভব হলে int
গুলি থেকে Enum
গুলি (বা বিপরীতে) রূপান্তর না করাই ভাল ।
এটি এমন কিছু না যা সাধারণত করা হয়, তাই আমি পুনর্বিবেচনা করব। তবে এই কথাটি বলার পরেও, মৌলিক ক্রিয়াকলাপগুলি হ'ল: int -> enum EnumType.values () [intNum] ব্যবহার করে, এবং enumInst.ordinal () ব্যবহার করে enum -> int।
তবে, যেহেতু মানগুলির কোনও প্রয়োগকরণের জন্য আপনাকে অ্যারের একটি অনুলিপি দেওয়ার আগে (জাভা অ্যারেগুলি কেবল পঠনযোগ্য হয় না), আপনাকে এনাম -> ইন্ট ম্যাপিংয়ের ক্যাশে একটি এনামম্যাপ ব্যবহার করে আরও ভাল পরিবেশিত হবে।
আমি যে সমাধানটি সাথে যেতে চাই তা এখানে Here এটি কেবল অ-অনুক্রমিক পূর্ণসংখ্যার সাথেই কাজ করে না তবে এটি আপনার এনাম মানগুলির জন্য অন্তর্নিহিত আইডি হিসাবে ব্যবহার করতে চাইলে অন্য কোনও ডেটা টাইপের সাথে কাজ করে।
public Enum MyEnum {
THIS(5),
THAT(16),
THE_OTHER(35);
private int id; // Could be other data type besides int
private MyEnum(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
public static Map<Integer, MyEnum> buildMap() {
Map<Integer, MyEnum> map = new HashMap<Integer, MyEnum>();
MyEnum[] values = MyEnum.values();
for (MyEnum value : values) {
map.put(value.getId(), value);
}
return map;
}
}
আমার নির্দিষ্ট আইডিগুলিতে কেবলমাত্র এনডিগুলিতে এনামগুলিতে রূপান্তর করতে হবে (কোনও ফাইল থেকে ডেটা লোড করার সময়), তাই ম্যাপকে সর্বদা স্মৃতিতে রাখার কোনও কারণ নেই। আপনার যদি মানচিত্রটি সর্বদা অ্যাক্সেসযোগ্য হওয়ার প্রয়োজন হয় তবে আপনি সর্বদা এটি আপনার এনাম শ্রেণীর স্থিতিশীল সদস্য হিসাবে ক্যাশে রাখতে পারেন।
clearCachedValues
আপনি এটি ব্যবহার করার পরে একটি দ্বিতীয় পদ্ধতি যুক্ত করুন (এটি ব্যক্তিগত ক্ষেত্রটি শূন্যে ফিরে আসে)। আমি MyEnum.fromInt(i)
মানচিত্রের অবজেক্টের চারপাশে যাওয়ার চেয়ে বোঝা সহজ মনে করি ।
যদি এটি অন্যকে সহায়তা করে তবে আমি যে বিকল্পটি পছন্দ করি তা এখানে লিখিত নয়, যা পেয়ারার মানচিত্রের কার্যকারিতা ব্যবহার করে :
public enum MyEnum {
OPTION_1(-66),
OPTION_2(32);
private int value;
private MyEnum(final int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
private static ImmutableMap<Integer, MyEnum> reverseLookup =
Maps.uniqueIndex(Arrays.asList(MyEnum.values())), MyEnum::getValue);
public static MyEnum fromInt(final int id) {
return reverseLookup.getOrDefault(id, OPTION_1);
}
}
আপনি যে ডিফল্টটি ব্যবহার করতে পারেন তার সাহায্যে null
আপনি throw IllegalArgumentException
বা আপনার যে কোনও আচরণ পছন্দ fromInt
করতে পারেন returnOptional
Map<Integer, MyEnum> reverseLookup = Arrays.stream(MyEnum.values()).collect(Collectors.toMap(MyEnum::getValue, Function.identity()));
getValue()
পদ্ধতিও সংজ্ঞায়িত করতে পারে ।
আপনি values()
এনামের উপরে পুনরাবৃত্তি করতে পারেন এবং id
নীচের মত এনামের পূর্ণসংখ্যার মান তুলনা করতে পারেন :
public enum TestEnum {
None(0),
Value1(1),
Value2(2),
Value3(3),
Value4(4),
Value5(5);
private final int value;
private TestEnum(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static TestEnum getEnum(int value){
for (TestEnum e:TestEnum.values()) {
if(e.getValue() == value)
return e;
}
return TestEnum.None;//For values out of enum scope
}
}
এবং ঠিক এর মতো ব্যবহার করুন:
TestEnum x = TestEnum.getEnum(4);//Will return TestEnum.Value4
আমি আশা করি এটি সাহায্য করে;)
@ চ্যাডবিফাসের উত্তর এবং @ শমোসেল মন্তব্যের ভিত্তিতে আমি এটি ব্যবহার করার পরামর্শ দিচ্ছি। (দক্ষ অনুসন্ধান এবং খাঁটি জাভা> = 8 এ কাজ করে)
import java.util.stream.Collectors;
import java.util.function.Function;
import java.util.Map;
import java.util.Arrays;
public enum MyEnum {
OPTION_1(-66),
OPTION_2(32);
private int value;
private MyEnum(final int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
private static Map<Integer, MyEnum> reverseLookup =
Arrays.stream(MyEnum.values()).collect(Collectors.toMap(MyEnum::getValue, Function.identity()));
public static MyEnum fromInt(final int id) {
return reverseLookup.getOrDefault(id, OPTION_1);
}
public static void main(String[] args) {
System.out.println(fromInt(-66).toString());
}
}
একটি ভালো বিকল্প হয় এড়ানোর থেকে রুপান্তরের int
জন্যenum
() y.ordinal করার () এবং বিনিময়ে X অথবা Y সঙ্গতিপূর্ণভাবেই উদাহরণস্বরূপ, যদি আপনি সর্বোচ্চ মান, আপনি x.ordinal তুলনা করতে পারেন:। (এই ধরণের তুলনাকে অর্থবহ করার জন্য আপনাকে পুনরায় অর্ডার দেওয়ার দরকার হতে পারে))
যদি এটি সম্ভব না হয় তবে আমি MyEnum.values()
একটি স্ট্যাটিক অ্যারেতে সংরক্ষণ করব।
এটি ডাক্তারদের মতো একই উত্তর তবে এটি দেখায় যে কীভাবে পরিবর্তনীয় অ্যারেগুলি দিয়ে সমস্যাটি দূর করা যায়। আপনি যদি শাখার পূর্বাভাসের কারণে প্রথমে এই ধরণের পদ্ধতির ব্যবহার করেন তবে যদি খুব কম থেকে শূন্য প্রভাব থাকে এবং পুরো কোডটি কেবলমাত্র একবার পরিবর্তিত অ্যারে মান () ফাংশন কল করে। উভয় ভেরিয়েবল স্থিতিশীল হওয়ায় তারা এই সংখ্যাটির প্রতিটি ব্যবহারের জন্যও এন * মেমরি গ্রহণ করবে না।
private static boolean arrayCreated = false;
private static RFMsgType[] ArrayOfValues;
public static RFMsgType GetMsgTypeFromValue(int MessageID) {
if (arrayCreated == false) {
ArrayOfValues = RFMsgType.values();
}
for (int i = 0; i < ArrayOfValues.length; i++) {
if (ArrayOfValues[i].MessageIDValue == MessageID) {
return ArrayOfValues[i];
}
}
return RFMsgType.UNKNOWN;
}
enum MyEnum {
A(0),
B(1);
private final int value;
private MyEnum(int val) {this.value = value;}
private static final MyEnum[] values = MyEnum.values();//cache for optimization
public static final getMyEnum(int value) {
try {
return values[value];//OOB might get triggered
} catch (ArrayOutOfBoundsException e) {
} finally {
return myDefaultEnumValue;
}
}
}
কোটলিনে:
enum class Status(val id: Int) {
NEW(0), VISIT(1), IN_WORK(2), FINISHED(3), CANCELLED(4), DUMMY(5);
companion object {
private val statuses = Status.values().associateBy(Status::id)
fun getStatus(id: Int): Status? = statuses[id]
}
}
ব্যবহার:
val status = Status.getStatus(1)!!
এই বাস্তবায়ন লিখেছেন। এটি অনুপস্থিত মান, নেতিবাচক মানগুলির জন্য এবং কোডটিকে সঙ্গতিপূর্ণ রাখার অনুমতি দেয়। মানচিত্রটি পাশাপাশি ক্যাশে করা হয়েছে। একটি ইন্টারফেস ব্যবহার করে এবং জাভা 8 প্রয়োজন।
Enum
public enum Command implements OrdinalEnum{
PRINT_FOO(-7),
PRINT_BAR(6),
PRINT_BAZ(4);
private int val;
private Command(int val){
this.val = val;
}
public int getVal(){
return val;
}
private static Map<Integer, Command> map = OrdinalEnum.getValues(Command.class);
public static Command from(int i){
return map.get(i);
}
}
ইন্টারফেস
public interface OrdinalEnum{
public int getVal();
@SuppressWarnings("unchecked")
static <E extends Enum<E>> Map<Integer, E> getValues(Class<E> clzz){
Map<Integer, E> m = new HashMap<>();
for(Enum<E> e : EnumSet.allOf(clzz))
m.put(((OrdinalEnum)e).getVal(), (E)e);
return m;
}
}