Enum di Java mengimplementasikan Comparable
antarmuka. Ini akan menyenangkan untuk override Comparable
's compareTo
metode, tapi di sini itu ditandai sebagai final. Default tatanan alam di Enum
's compareTo
adalah urutan yang tercantum.
Adakah yang tahu mengapa enum Java memiliki batasan ini?
java
enums
comparable
compareto
neu242
sumber
sumber
Jawaban:
Untuk konsistensi saya kira ... ketika Anda melihat sebuah
enum
tipe, Anda tahu pasti bahwa urutan alaminya adalah urutan di mana konstanta dideklarasikan.Untuk mengatasinya, Anda dapat dengan mudah membuat sendiri
Comparator<MyEnum>
dan menggunakannya kapan pun Anda membutuhkan pemesanan yang berbeda:enum MyEnum { DOG("woof"), CAT("meow"); String sound; MyEnum(String s) { sound = s; } } class MyEnumComparator implements Comparator<MyEnum> { public int compare(MyEnum o1, MyEnum o2) { return -o1.compareTo(o2); // this flips the order return o1.sound.length() - o2.sound.length(); // this compares length } }
Anda dapat menggunakan
Comparator
langsung:MyEnumComparator c = new MyEnumComparator(); int order = c.compare(MyEnum.CAT, MyEnum.DOG);
atau gunakan dalam koleksi atau array:
NavigableSet<MyEnum> set = new TreeSet<MyEnum>(c); MyEnum[] array = MyEnum.values(); Arrays.sort(array, c);
Informasi lebih lanjut:
sumber
MyEnumComparator
tidak memiliki status, itu seharusnya hanya tunggal, terutama jika Anda melakukan apa yang disarankan @Bombe; sebagai gantinya, Anda akan melakukan sesuatu sepertiMyEnumComparator.INSTANCE.compare(enum1, enum2)
menghindari pembuatan objek yang tidak perluLENGTH_COMPARATOR
bidang statis di enum. Dengan cara itu akan mudah untuk menemukan siapa saja yang menggunakan enum.Menyediakan implementasi default dari bandingkanTo yang menggunakan pengurutan kode sumber tidak masalah; menyelesaikannya adalah salah langkah di pihak Sun. Ordinal sudah memperhitungkan perintah deklarasi. Saya setuju bahwa dalam kebanyakan situasi, seorang pengembang hanya dapat secara logis memesan elemen mereka, tetapi terkadang seseorang ingin kode sumber diatur sedemikian rupa sehingga keterbacaan dan pemeliharaan menjadi yang terpenting. Sebagai contoh:
//===== SI BYTES (10^n) =====// /** 1,000 bytes. */ KILOBYTE (false, true, 3, "kB"), /** 106 bytes. */ MEGABYTE (false, true, 6, "MB"), /** 109 bytes. */ GIGABYTE (false, true, 9, "GB"), /** 1012 bytes. */ TERABYTE (false, true, 12, "TB"), /** 1015 bytes. */ PETABYTE (false, true, 15, "PB"), /** 1018 bytes. */ EXABYTE (false, true, 18, "EB"), /** 1021 bytes. */ ZETTABYTE(false, true, 21, "ZB"), /** 1024 bytes. */ YOTTABYTE(false, true, 24, "YB"), //===== IEC BYTES (2^n) =====// /** 1,024 bytes. */ KIBIBYTE(false, false, 10, "KiB"), /** 220 bytes. */ MEBIBYTE(false, false, 20, "MiB"), /** 230 bytes. */ GIBIBYTE(false, false, 30, "GiB"), /** 240 bytes. */ TEBIBYTE(false, false, 40, "TiB"), /** 250 bytes. */ PEBIBYTE(false, false, 50, "PiB"), /** 260 bytes. */ EXBIBYTE(false, false, 60, "EiB"), /** 270 bytes. */ ZEBIBYTE(false, false, 70, "ZiB"), /** 280 bytes. */ YOBIBYTE(false, false, 80, "YiB");
Urutan di atas terlihat bagus dalam kode sumber, tetapi tidak seperti yang diyakini penulis tentang cara membandingkanTo. Perilaku bandingkan yang diinginkan adalah mengurutkan berdasarkan jumlah byte. Pengurutan kode sumber yang akan membuat hal itu terjadi akan menurunkan pengaturan kode.
Sebagai klien enumerasi saya tidak peduli bagaimana penulis mengatur kode sumber mereka. Saya memang ingin algoritme perbandingan mereka masuk akal. Sun tidak perlu membuat penulis kode sumber terikat.
sumber
Nilai pencacahan diurutkan secara tepat secara logis sesuai dengan urutan pernyataannya. Ini adalah bagian dari spesifikasi bahasa Java. Oleh karena itu, nilai pencacahan hanya dapat dibandingkan jika mereka adalah anggota Enum yang sama. Spesifikasi ingin lebih menjamin bahwa urutan pembanding yang dikembalikan oleh bandingkanTo () sama dengan urutan di mana nilai dideklarasikan. Ini adalah definisi dari enumerasi.
sumber
Satu penjelasan yang mungkin adalah yang
compareTo
harus sejalan denganequals
.Dan
equals
untuk enum harus konsisten dengan identity equality (==
).Jika
compareTo
menjadi non-final adalah mungkin untuk menimpanya dengan perilaku yang tidak konsistenequals
, yang akan sangat kontra-intuitif.sumber
Jika Anda ingin mengubah urutan natural elemen enum Anda, ubah urutannya di kode sumber.
sumber