Saat bekerja dengan variabel / parameter yang hanya dapat mengambil sejumlah nilai, saya mencoba untuk selalu menggunakan Java enum
, seperti pada
public enum BonusType {
MONTHLY, YEARLY, ONE_OFF
}
Selama saya tetap berada di dalam kode saya, itu berfungsi dengan baik. Namun, saya sering perlu berinteraksi dengan kode lain yang menggunakan nilai biasa int
(atau String
) untuk tujuan yang sama, atau saya perlu membaca / menulis dari / ke database tempat data disimpan sebagai angka atau string.
Dalam hal ini, saya ingin memiliki cara yang mudah untuk mengaitkan setiap nilai enum dengan bilangan bulat, sehingga saya dapat mengonversi kedua cara (dengan kata lain, saya memerlukan "enum yang dapat dibalik").
Beralih dari enum ke int itu mudah:
public enum BonusType {
public final int id;
BonusType(int id) {
this.id = id;
}
MONTHLY(1), YEARLY(2), ONE_OFF(3);
}
Kemudian saya dapat mengakses nilai int sebagai BonusType x = MONTHLY; int id = x.id;
.
Namun, saya tidak melihat cara yang baik untuk kebalikannya, yaitu berpindah dari int ke enum. Idealnya, seperti
BonusType bt = BonusType.getById(2);
Satu-satunya solusi yang dapat saya temukan adalah:
- Letakkan metode pencarian ke dalam enum, yang digunakan
BonusType.values()
untuk mengisi peta "int -> enum", lalu menyimpannya dan menggunakannya untuk pencarian. Akan berfungsi, tetapi saya harus menyalin metode ini secara identik ke setiap enum yang saya gunakan :-(. - Letakkan metode pencarian ke dalam kelas utilitas statis. Maka saya hanya perlu satu metode "pencarian", tetapi saya harus mengutak-atik refleksi untuk membuatnya bekerja untuk enum sewenang-wenang.
Kedua metode tampaknya sangat canggung untuk masalah sederhana (?) Seperti itu.
Ada ide / wawasan lain?
sumber
ordinal()
.ordinal()
), atau apakah mereka ditentukan oleh kekuatan luar?Jawaban:
http://www.javaspecialists.co.za/archive/Issue113.html
Solusinya dimulai mirip dengan Anda dengan nilai int sebagai bagian dari definisi enum. Dia kemudian melanjutkan untuk membuat utilitas pencarian berbasis generik:
Solusi ini bagus dan tidak memerlukan 'mengutak-atik refleksi' karena ini didasarkan pada fakta bahwa semua jenis enum secara implisit mewarisi antarmuka Enum.
sumber
Number
bukanByte
, karena nilai dukungan saya mungkin lebih besar dalam ukuran.enum → int
int → enum
String → enum
enum → String
Catatan tambahan:
Seperti yang Anda tunjukkan dengan benar,
ordinal()
mungkin "tidak stabil" dari versi ke versi. Inilah alasan sebenarnya mengapa saya selalu menyimpan konstanta sebagai string di database saya. (Sebenarnya, saat menggunakan MySql, saya menyimpannya sebagai MySql enums !)sumber
BonusType.valueOf("MONTHLY")
)ordinal()
strike me sebagai solusi bermasalah, karena akan rusak ketika daftar nilai enum diatur ulang, atau nilai dihapus. Juga, ini hanya praktis jika nilai int adalah 0 ... n (yang sering saya temukan tidak demikian).values()
array hanya akan berfungsi jika semua nilai Anda diindeks 0 untuk id mereka dan dideklarasikan secara berurutan. (Saya menguji ini untuk memverifikasi bahwa jika Anda menyatakanFOO(0), BAR(2), BAZ(1);
ituvalues[1] == BAR
danvalues[2] == BAZ
terlepas dari ID yang diteruskan.)double
).Saya menemukan ini di web, sangat membantu dan mudah diterapkan. Solusi ini BUKAN dibuat oleh saya
http://www.ajaxonomy.com/2007/java/making-the-most-of-java-50-enum-tricks
}
sumber
Sepertinya jawaban untuk pertanyaan ini sudah ketinggalan zaman dengan dirilisnya Java 8.
sumber
Collectors.toMap()
menjadi,Functions.identity()
bukannull
?org.apache.commons.lang.enums.ValuedEnum;
Untuk menyelamatkan saya menulis banyak kode boilerplate atau kode duplikat untuk setiap Enum, saya menggunakan Apache Commons Lang
ValuedEnum
sebagai gantinya.Definisi :
Pemakaian:
int -> ValuedEnum:
sumber
Anda mungkin bisa menggunakan sesuatu seperti
Itu akan mengurangi kebutuhan refleksi di kelas utilitas Anda.
sumber
Dalam kode ini, untuk pencarian permanen dan intens, memiliki memori atau proses untuk digunakan, dan saya memilih memori, dengan array konverter sebagai indeks. Saya harap ini membantu
sumber
Gunakan antarmuka untuk menunjukkan siapa bosnya.
Dan hasilnya:
sumber
Baik the
.ordinal()
danvalues()[i]
tidak stabil karena bergantung pada urutan enum. Jadi jika Anda mengubah urutan enum atau menambah / menghapus beberapa program Anda akan rusak.Berikut adalah metode sederhana namun efektif untuk memetakan antara enum dan int.
Menerapkannya untuk string seharusnya tidak sulit.
sumber
Langkah 1 Tentukan
interface
EnumConverterLangkah 2
Buat nama kelas ReverseEnumMap
LANGKAH 3
Pergi ke
Enum
kelas Anda danimplement
denganEnumConverter<ContentType>
dan tentu saja timpa metode antarmuka. Anda juga perlu menginisialisasi ReverseEnumMap statis.LANGKAH 4
Sekarang membuat
Communication
file kelas dan menyebutnya itu metode baru untuk mengkonversiEnum
keString
danString
untukEnum
. Saya baru saja meletakkan metode utama untuk tujuan penjelasan.Klik untuk penjelasan lengkap
sumber
ContentType convert(String pKey)
statis, yang menghilangkan kebutuhan akanCommunication
kelas dan lebih sesuai dengan keinginan saya. +1Saya tidak yakin apakah itu sama di Java, tetapi tipe enum di C secara otomatis dipetakan ke integer juga sehingga Anda dapat menggunakan tipe atau integer untuk mengaksesnya. Sudahkah Anda mencoba mengaksesnya dengan integer saja?
sumber
.ordinal()
metode tersebut. (Cara lain, gunakanBonusType.values()[i]
.) Tetapi dalam contoh yang dikutip di atas, indeks di sini dan nilai di luarnya tidak sama.Pertanyaan yang sangat bagus :-) Saya menggunakan solusi yang mirip dengan Mr. Ferguson beberapa waktu lalu. Enum yang telah didekompilasi terlihat seperti ini:
Melihat ini jelas mengapa
ordinal()
tidak stabil. Ini adalah bagiani
dalamsuper(s, i);
. Saya juga pesimis bahwa Anda dapat memikirkan solusi yang lebih elegan daripada yang sudah Anda sebutkan. Lagipula enum adalah kelas seperti kelas akhir lainnya.sumber
Demi kelengkapan, berikut adalah pendekatan umum untuk mengambil nilai enum berdasarkan indeks dari jenis enum apa pun. Tujuan saya adalah membuat metode ini terlihat dan terasa seperti Enum.valueOf (Class, String) . Fyi, saya menyalin metode ini dari sini .
Masalah terkait indeks (sudah dibahas secara mendalam di sini) masih berlaku.
sumber
MyEnumType.values()
- tidak perlu metode pembantu statis.sumber
Saya membutuhkan sesuatu yang berbeda karena saya ingin menggunakan pendekatan umum. Saya membaca enum ke dan dari array byte. Di sinilah saya datang dengan:
Contoh enum:
}
sumber
Hanya karena jawaban yang diterima tidak berdiri sendiri:
Kode dukungan:
Contoh penggunaan:
sumber
diberikan:
public enum BonusType {MONTHLY (0), YEARLY (1), ONE_OFF (2)}
BonusType bonus = SETIAP TAHUN;
System.out.println (bonus.Ordinal () + ":" + bonus)
Output: 1: SETIAP TAHUN
sumber
Jika Anda memiliki mobil kelas
Dan properti Color adalah sebuah kelas
Dan Anda ingin mengubah Warna menjadi Enum
Cukup tambahkan metode di kelas Color untuk mengonversi Color di ColorEnum
dan di dalam ColorEnum mengimplementasikan metode getById ()
Sekarang Anda dapat menggunakan classMap
sumber