Saya memiliki tipe enum ReportTypeEnum
yang dapat dilewati antar metode di semua kelas saya, tetapi kemudian saya harus meneruskannya di URL jadi saya menggunakan metode ordinal untuk mendapatkan nilai int. Setelah saya mendapatkannya di halaman JSP saya yang lain, saya perlu mengonversinya untuk kembali ke ReportTypeEnum
sehingga saya bisa meneruskannya.
Bagaimana saya bisa mengubah ordinal ke ReportTypeEnum
?
Menggunakan Java 6 SE.
Jawaban:
Untuk mengubah ordinal menjadi represantation enumnya, Anda mungkin ingin melakukan ini:
Harap perhatikan batasan array.
Perhatikan bahwa setiap panggilan untuk
values()
mengembalikan array yang baru dikloning yang mungkin berdampak pada kinerja secara negatif. Anda mungkin ingin men-cache array jika itu akan sering dipanggil.Contoh kode tentang cara cache
values()
.Jawaban ini diedit untuk memasukkan umpan balik yang diberikan di dalam komentar
sumber
Ini hampir pasti merupakan ide yang buruk . Tentu saja jika ordinal secara de-facto tetap ada (misalnya karena seseorang telah menandai URL) - itu berarti Anda harus selalu menjaga
enum
pemesanan di masa depan, yang mungkin tidak jelas bagi pengelola kode di telepon.Mengapa tidak mengkodekan
enum
menggunakanmyEnumValue.name()
(dan mendekode viaReportTypeEnum.valueOf(s)
) sebagai gantinya?sumber
value
posisi awal atau alfabet / logis yang benar. (Dengan logika saya maksud misalnyaTimeUnit
nilai-nilai memiliki posisi logis)Jika saya akan menggunakan
values()
banyak:Sementara itu dimanapun.java:
Pikirkan batasan array Anda.
sumber
Suit.values[0] = Suit.Diamonds;
kode Anda. Idealnya hal itu tidak akan pernah terjadi, tetapi prinsip keseluruhan jangan biarkan bidang yang bisa berubah tetap berlaku. Untuk pendekatan ini, pertimbangkan menggunakanCollections.unmodifiableList
atau sejenisnya.Suit values[]
secara langsung atau tidak langsung (bagaimana disebutkan melaluigetValues()
), saya bekerja dengan metode publik di manaordinal
nilai harus dikirim bagaimana argumen dan mengembalikanSuit
representasi dariSuit values[]
. Intinya di sini (ubin pertanyaan dari awal) adalah membuat tipe enum dari ordinal enumSaya setuju dengan kebanyakan orang bahwa menggunakan ordinal mungkin adalah ide yang buruk. Saya biasanya memecahkan masalah ini dengan memberikan enum konstruktor pribadi yang dapat mengambil misalnya nilai DB kemudian membuat
fromDbValue
fungsi statis mirip dengan yang ada di jawaban Jan.Sekarang Anda dapat mengubah urutan tanpa mengubah pencarian dan sebaliknya.
sumber
Anda bisa menggunakan tabel pencarian statis:
sumber
0...(n-1)
, maka array lebih sedikit kode dan lebih mudah dibaca juga; peningkatan kinerja hanyalah bonus.private static final Suit[] VALUES = values();
danpublic Suit fromOrdinal(int ordinal) { return VALUES[ordinal]; }
. Keuntungan ekstra: crash langsung pada ordinals yang tidak valid, daripada diam-diam mengembalikan nol. (Tidak selalu keuntungan. Tapi sering.)Inilah yang saya gunakan. Saya tidak berpura-pura bahwa ini jauh kurang "efisien" daripada solusi sederhana di atas. Apa yang dilakukannya adalah memberikan pesan pengecualian yang jauh lebih jelas daripada "ArrayIndexOutOfBounds" ketika nilai ordinal yang tidak valid digunakan dalam solusi di atas.
Itu memanfaatkan fakta bahwa javadoc EnumSet menentukan elemen pengembalian iterator dalam urutan alami mereka. Ada yang menegaskan kalau itu tidak benar.
Tes JUnit4 menunjukkan bagaimana ini digunakan.
sumber
Inilah yang saya lakukan di Android dengan Proguard:
ini singkat dan saya tidak perlu khawatir tentang memiliki pengecualian di Proguard
sumber
Anda dapat mendefinisikan metode sederhana seperti:
Dan gunakan seperti:
sumber
kelas tes
Saya menghargai bahwa Anda berbagi dengan kami jika Anda memiliki kode yang lebih efisien, Enum saya besar dan terus-menerus dipanggil ribuan kali.
sumber
Jadi salah satu caranya adalah melakukan
ExampleEnum valueOfOrdinal = ExampleEnum.values()[ordinal];
yang berfungsi dan mudah, namun, seperti yang disebutkan sebelumnya,ExampleEnum.values()
mengembalikan array yang dikloning untuk setiap panggilan. Itu bisa sangat mahal. Kita bisa menyelesaikannya dengan cara cache array seperti ituExampleEnum[] values = values()
. Ini juga "berbahaya" untuk memungkinkan array cache kita untuk dimodifikasi. Seseorang dapat menulisExampleEnum.values[0] = ExampleEnum.type2;
Jadi saya akan menjadikannya pribadi dengan metode accessor yang tidak melakukan penyalinan tambahan.Anda akan menggunakan
ExampleEnum.value(ordinal)
untuk mendapatkan nilai enum yang terkaitordinal
sumber
Setiap enum memiliki nama (), yang memberikan string dengan nama anggota enum.
Diberikan
enum Suit{Heart, Spade, Club, Diamond}
,Suit.Heart.name()
akan memberiHeart
.Setiap enum memiliki
valueOf()
metode, yang mengambil tipe enum dan string, untuk melakukan operasi terbalik:Enum.valueOf(Suit.class, "Heart")
kembaliSuit.Heart
.Mengapa ada orang yang menggunakan tata cara di luar saya. Mungkin nanodetik lebih cepat, tetapi tidak aman, jika anggota enum berubah, karena pengembang lain mungkin tidak menyadari beberapa kode bergantung pada nilai-nilai ordinal (terutama di halaman JSP yang dikutip dalam pertanyaan, overhead jaringan dan basis data sepenuhnya mendominasi waktu, tidak menggunakan bilangan bulat di atas string).
sumber