Katakanlah saya punya enum yang adil
public enum Blah {
A, B, C, D
}
dan saya ingin mencari nilai enum string, misalnya "A"
yang mana Blah.A
. Bagaimana mungkin melakukan ini?
Apakah Enum.valueOf()
metode yang saya butuhkan? Jika demikian, bagaimana saya menggunakan ini?
Blah.valueOf("A")
metode ini case-sensitive dan tidak mentolerir ruang kosong asing, sehingga solusi alternatif yang diusulkan di bawah ini oleh @ JoséMi.toString()
nilainya, tidak, saya tidak akan mengatakan itu.name()
akan memberi Anda nama sebenarnya yang ditentukan dari konstanta enum kecuali Anda menimpanya.enum Blah {...}
Definisi aktual seharusnya tidak mencoba untuk menyatakan sendirivalues
atau tidakvaluesOf
. Ini seperti bagaimana Anda dapat menulis "AnyTypeName.class" meskipun Anda tidak pernah benar-benar mendeklarasikan variabel anggota "kelas"; kompiler membuat semuanya Hanya Bekerja. (Jawaban ini mungkin tidak lagi berguna bagi Anda 3 bulan kemudian, tetapi untuk berjaga-jaga.)Solusi lain jika teks tidak sama dengan nilai enumerasi:
sumber
throw new IllegalArgumentException("No constant with text " + text + " found")
akan lebih baik daripadareturn null
.Inilah utilitas bagus yang saya gunakan:
Kemudian di kelas enum saya, saya biasanya memiliki ini untuk menyimpan mengetik:
Jika enum Anda tidak semuanya tertutup, ubah saja
Enum.valueOf
garisnya.Sayang sekali aku tidak bisa menggunakan
T.class
untukEnum.valueOf
sebagaiT
dihapus.sumber
Gunakan pola dari Joshua Bloch, Java Efektif :
(disederhanakan untuk singkatnya)
Lihat juga:
Contoh Oracle Java menggunakan Enum dan Peta instance
Perintah eksekusi dari blok statis dalam tipe Enum
Bagaimana saya bisa mencari Java enum dari nilai String-nya
sumber
Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity()))
Saya juga merekomendasikan untuk meng-override ke Strtr () (diteruskan melalui konstruktor) dan menggunakan itu alih-alih nama, terutama jika Enum dikaitkan dengan data serial karena ini memungkinkan Anda mengontrol casing tanpa memberikan Sonar cocok.unmodifiableMap
, tetap tidak ada manfaatnya untuk memulai denganConcurrentHashMap
. Cukup gunakan aHashMap
. (Jika Anda memiliki GuavaImmutableMap
maka saya akan merekomendasikan itu sebagai gantinya!)ConcurrentHashMap
sini, di mana peta tidak pernah dimodifikasi setelah inisialisasi. Karenanya mengapa bahkan misalnya contoh dalam JLS itu sendiri menggunakan regulerHashMap
.Anda juga harus berhati-hati dengan kasus Anda. Biarkan saya jelaskan: melakukan
Blah.valueOf("A")
pekerjaan, tetapiBlah.valueOf("a")
tidak akan berhasil. Kemudian lagiBlah.valueOf("a".toUpperCase(Locale.ENGLISH))
akan berhasil.sunting
Diubah
toUpperCase
menjaditoUpperCase(Locale.ENGLISH)
berdasarkan tc. komentar dan dokumen javasunting2 Di android Anda harus menggunakan
Locale.US
, sebagai sulai menunjukkan .sumber
Locale.US
input / output yang dapat dibaca mesin.Berikut adalah metode yang dapat melakukannya untuk Enum apa pun, dan tidak peka huruf besar-kecil.
sumber
equalsIgnoreCase
adalah jalan yang harus ditempuh. +1Menggunakan
Blah.valueOf(string)
itu yang terbaik tetapi Anda juga bisa menggunakannyaEnum.valueOf(Blah.class, string)
.sumber
Di Java 8 atau lebih baru, menggunakan Streaming :
sumber
Jika Anda tidak ingin menulis utilitas sendiri, gunakan Google jambu biji Perpustakaan:
Tidak seperti fungsi java yang ada di dalamnya, mari kita periksa apakah A ada dalam Blah dan tidak melempar pengecualian.
sumber
2 sen saya di sini: menggunakan Java8 Streams + memeriksa string yang tepat:
** EDIT **
Berganti nama fungsinya
fromString()
sejak menamainya menggunakan konvensi itu, Anda akan memperoleh beberapa manfaat dari bahasa Java itu sendiri; sebagai contoh:sumber
switch
blok yang lebih mudah dibaca , Anda bisa.orElse(null)
sebagai ganti.orElseThrow()
sehingga Anda bisa membuat kode pengecualian lemparan dalamdefault
klausa - dan memasukkan info yang lebih berguna saat dibutuhkan. Dan untuk membuatnya lebih ringan Anda bisa menggunakanv -> Objects.equals(v.name, s == null ? "" : s.trim().toUpperCase())
Optional
darifindFirst()
, yang memungkinkan pengguna untuk memutuskan apakah dia mau.orElse(null)
,orElseThrow()
atau apa pun ....public static MyEnum valueOf(String)
sebenarnya adalah kesalahan kompilasi, karena itu sama dengan yang didefinisikan secara implisit, jadi versi lama dari jawaban Anda sebenarnya lebih baik. ( JLS , ideone )Anda mungkin perlu ini:
Satu Tambahan Lagi:
Ini akan mengembalikan Anda Nilai oleh Nama Enum yang Dimodifikasi untuk misalnya jika Anda memberikan "PERSON" di fromEnumName, itu akan mengembalikan Anda Nilai Enum yaitu "Orang"
sumber
Cara lain untuk melakukan ini dengan menggunakan metode statis implisit
name()
Enum. nama akan mengembalikan string yang tepat digunakan untuk membuat enum yang dapat digunakan untuk memeriksa terhadap string yang disediakan:Pengujian:
System.out.println(Blah.getEnum("B").name());
inspirasi: 10 Contoh Enum di Jawa
sumber
valueOf
Anda lakukan. Metode statis ini tidak menawarkan tambahan apa pun, kecuali semua. Maka konstruksi if / else sangat berbahaya ... konstanta enum baru yang ditambahkan akan menyebabkan metode ini rusak tanpa perubahan.name()
tidak statis.Solusi menggunakan perpustakaan Guava. Metode getPlanet () bersifat case-sensitive, jadi getPlanet ("MerCUrY") akan mengembalikan Planet.MERCURY.
sumber
Untuk menambah jawaban sebelumnya, dan membahas beberapa diskusi seputar nol dan NPE, saya menggunakan Pilihan Guava untuk menangani kasus yang tidak ada / tidak valid. Ini berfungsi baik untuk penguraian parameter / URI.
Bagi mereka yang tidak sadar, inilah beberapa info lebih lanjut tentang menghindari null dengan Opsional: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional
sumber
Di Java 8, pola Peta statis bahkan lebih mudah dan merupakan metode pilihan saya. Jika Anda ingin menggunakan Enum dengan Jackson, Anda dapat mengganti ke Strtring dan menggunakan itu alih-alih nama, lalu anotasi dengan
@JsonValue
sumber
sumber
O (1) metode yang diilhami dari kode yang dihasilkan hemat yang memanfaatkan hashmap.
sumber
Enum sangat berguna, saya telah menggunakan
Enum
banyak untuk menambahkan deskripsi untuk beberapa bidang dalam bahasa yang berbeda, sebagai contoh berikut:Dan kemudian Anda dapat mengambil deskripsi secara dinamis berdasarkan kode bahasa yang diteruskan ke
getDescription(String lang)
metode, misalnya:sumber
Bagaimana dengan?
sumber
java.lang.Enum
mendefinisikan beberapa metode yang berguna, yang tersedia untuk semua tipe enumerasi di Jawa:name()
metode untuk mendapatkan nama konstanta Enum. String literal yang digunakan untuk menulis konstanta enum adalah nama mereka.values()
metode dapat digunakan untuk mendapatkan array dari semua konstanta Enum dari jenis Enum.valueOf()
metode untuk mengubah sembarang String ke konstanta Enum di Jawa, seperti yang ditunjukkan di bawah ini.Dalam cuplikan kode ini,
valueOf()
metode mengembalikan Gender.MALE konstanta Enum, memanggil nama yang mengembalikan"MALE"
.sumber
Pustaka commons-lang Apache memiliki fungsi statis org.apache.commons.lang3.EnumUtils.getEnum yang akan memetakan sebuah String ke tipe Enum Anda. Jawaban yang sama pada dasarnya sama dengan Geoffrey tetapi mengapa menggulung sendiri saat sudah ada di luar sana.
sumber
Menambahkan ke jawaban berperingkat teratas, dengan utilitas bermanfaat ...
valueOf()
melempar dua Pengecualian berbeda dalam kasus di mana ia tidak suka inputnya.IllegalArgumentException
NullPointerExeption
Jika persyaratan Anda sedemikian rupa sehingga Anda tidak memiliki jaminan bahwa String Anda pasti akan cocok dengan nilai enum, misalnya jika data String berasal dari database dan dapat berisi versi lama dari enum, maka Anda harus menangani ini sering...
Jadi, inilah metode yang dapat digunakan kembali yang saya tulis yang memungkinkan kita untuk mendefinisikan Enum default untuk dikembalikan jika String yang kita lewati tidak cocok.
Gunakan seperti ini:
sumber
Karena versi
switch
-belum disebutkan saya memperkenalkannya (menggunakan kembali enum OP):Karena ini tidak memberikan nilai tambahan pada
valueOf(String name)
metode, masuk akal untuk mendefinisikan metode tambahan jika kita ingin memiliki perilaku yang berbeda. Jika kami tidak ingin menaikkan,IllegalArgumentException
kami dapat mengubah implementasinya menjadi:Dengan memberikan nilai default, kami menjaga kontrak dari
Enum.valueOf(String name)
tanpa melemparkan sebuahIllegalArgumentException
cara bahwa dalam kasus tidaknull
dikembalikan. Oleh karena itu kami melemparNullPointerException
jika nama adalahnull
dandefault
jikadefaultValue
adanull
. Begitulah caravalueOfOrDefault
kerjanya.Pendekatan ini mengadopsi desain
Map
-Interface yang menyediakan metodeMap.getOrDefault(Object key, V defaultValue)
pada Java 8.sumber
Utilitas lain menangkap dengan cara terbalik. Menggunakan nilai yang mengidentifikasi Enum itu, bukan dari namanya.
Contoh:
EnumUtil.from(Foo.class, "drei")
kembaliFoo.THREE
, karena akan digunakangetValue
untuk mencocokkan "drei", yang merupakan publik yang unik, bukan metode final dan tidak statis di Foo. Dalam hal Foo memiliki lebih dari pada metode umum, belum final dan tidak statis, misalnya,getTranslate
yang kembali "drei", metode lainnya dapat digunakan:EnumUtil.from(Foo.class, "drei", "getTranslate")
.sumber
Solusi Kotlin
Buat ekstensi lalu panggil
valueOf<MyEnum>("value")
. Jika jenisnya tidak valid, Anda akan mendapatkan nol dan harus menanganinyaAtau, Anda dapat menetapkan nilai default, menelepon
valueOf<MyEnum>("value", MyEnum.FALLBACK)
, dan menghindari respons nol. Anda dapat memperluas enum spesifik Anda agar default menjadi otomatisAtau jika Anda ingin keduanya, buat yang kedua:
sumber
Saya suka menggunakan proses semacam ini untuk mem-parsing perintah sebagai string ke enumerasi. Saya biasanya memiliki salah satu enumerasi sebagai "tidak dikenal" sehingga membantu mengembalikannya ketika yang lain tidak ditemukan (bahkan berdasarkan kasus yang tidak sensitif) daripada nol (artinya tidak ada nilai). Karenanya saya menggunakan pendekatan ini.
sumber
Cara tercepat untuk mendapatkan nama enum adalah dengan membuat peta teks dan nilai enum saat aplikasi dimulai, dan untuk mendapatkan nama panggil fungsi Blah.getEnumName ():
sumber