Ada metode nilai dalam enumerasi yang digunakan untuk menghasilkan array dalam urutan yang ditentukan oleh enumerasi, yang dapat digunakan untuk melintasi. Semua kelas enumerasi khusus kami mewarisi dari java.lang.Enum dan memiliki fungsi berikut sebagai contoh:
Copy kode kodenya sebagai berikut:
//: disebutkan/EnumClass.java
// Kemampuan kelas Enum
import static net.mindview.util.Print.*;
enum Semak { TANAH, MERAYAK, GANTUNG }
kelas publik EnumClass {
public static void main(String[] args) {
for(Semak s : Semak.nilai()) {
print(s + " ordinal: " + s.ordinal());
printnb(s.compareTo(Shrubbery.CRAWLING) + " ");
printnb(s.equals(Shrubbery.CRAWLING) + " ");
print(s == Semak.CRAWLING);
print(s.getDeclaringClass());
print(s.nama());
mencetak("----------------------");
}
// Menghasilkan nilai enum dari nama string:
for(String s : "TANAH PERAYAAN GANTUNG".split(" ")) {
Semak semak = Enum.valueOf(Shrubbery.class, s);
mencetak(semak);
}
}
} /* Keluaran:
TANAH ordinal: 0
-1 salah salah
kelas semak belukar
Joshua Bloch sangat membantu dalam mengembangkan bab ini.
TANAH
-----------------------
MERAYAK ordinal: 1
betul betul
kelas semak belukar
Merangkak
-----------------------
GANTUNG ordinal: 2
salah salah
kelas semak belukar
GANTUNG
-----------------------
GANTUNG
Merangkak
TANAH
*///:~
Kita juga dapat menggunakan referensi enumerasi statis:
Copy kode kodenya sebagai berikut:
//: disebutkan/Kepedasan.java
paket disebutkan;
public enum Pedasnya {TIDAK, RINGAN, SEDANG, PANAS, FLAMING} ///:~
//: disebutkan/Burrito.java
paket disebutkan;
import static enumerasi.Kepedasan.*;
Burrito kelas publik {
Tingkat kepedasan;
Burrito publik(Tingkat kepedasan) { derajat ini = derajat;}
public String toString() { return "Burrito adalah "+ derajat;}
public static void main(String[] args) {
System.out.println(Burrito baru(TIDAK));
System.out.println(Burrito baru(MEDIUM));
System.out.println(Burrito baru(PANAS));
}
} /* Keluaran:
Burrito BUKAN
Burritonya SEDANG
Burrito itu PANAS
*///:~
Selain menambahkan metode ke dalam enumerasi yang tidak dapat diwariskan, enumerasi dapat diperlakukan sebagai kelas umum, artinya Anda dapat menambahkan metode ke dalam enumerasi, dan Anda juga dapat menentukan metode utama dalam enumerasi:
Copy kode kodenya sebagai berikut:
//: disebutkan/OzWitch.java
// Para penyihir di negeri Oz.
import static net.mindview.util.Print.*;
enum publik OzWitch {
// Instance harus didefinisikan terlebih dahulu, sebelum metode:
BARAT("Nona Gulch, alias Penyihir Jahat dari Barat"), UTARA("Glinda, Penyihir Baik dari Utara"), TIMUR("Penyihir Jahat dari Timur, pemakai Ruby " + "Sandal, dihancurkan oleh Rumah Dorothy"), SELATAN("Bagus menurut kesimpulan, tetapi tidak ada");
deskripsi String pribadi;
// Konstruktor harus berupa akses paket atau pribadi:
OzWitch pribadi(Deskripsi string) {
this.deskripsi = deskripsi;
}
String publik getDescription() { deskripsi kembali; }
public static void main(String[] args) {
for(penyihir OzWitch : OzWitch.values())
print(penyihir + ": " + penyihir.getDescription());
}
} /* Keluaran:
BARAT: Nona Gulch, alias Penyihir Jahat dari Barat
UTARA: Glinda, Penyihir Baik dari Utara
TIMUR: Penyihir Jahat dari Timur, pemakai Sandal Ruby, dihancurkan oleh rumah Dorothy
SELATAN: Kesimpulannya bagus, tapi kurang
*///:~
Copy kode kodenya sebagai berikut:
//: disebutkan/SpaceShip.java
public enum Pesawat Luar Angkasa {
SCOUT, CARGO, ANGKUTAN, CRUISER, BATTLESHIP, IBU;
String publik keString() {
String id = nama();
String lebih rendah = id.substring(1).toLowerCase();
kembalikan id.charAt(0) + lebih rendah;
}
public static void main(String[] args) {
untuk(SpaceShip s : nilai()) {
Sistem.keluar.println;
}
}
} /* Keluaran:
Pramuka
Muatan
Mengangkut
Kapal penjelajah
kapal perang
kapal induk
*///:~
Pencacahan dalam pernyataan switch Peran penting enumerasi ada dalam pernyataan switch. Biasanya pernyataan switch hanya bekerja pada nilai integer, tetapi ada urutan bilangan bulat bawaan dalam enumerasi, sehingga urutan instance dapat ditentukan dengan beberapa metode. jadi enum dapat digunakan dalam pernyataan switch:
Copy kode kodenya sebagai berikut:
//: disebutkan/TrafficLight.java
// Enum dalam pernyataan switch.
import static net.mindview.util.Print.*;
// Tentukan tipe enum:
enum Sinyal { HIJAU, KUNING, MERAH, }
Lampu Lalu Lintas kelas publik {
Warna sinyal = Sinyal.MERAH;
perubahan kekosongan publik() {
beralih(warna) {
// Perhatikan bahwa Anda tidak perlu mengucapkan Signal.RED
// dalam pernyataan kasus:
case MERAH: warna = Sinyal.HIJAU;
merusak;
case HIJAU: warna = Sinyal.KUNING;
merusak;
case KUNING: warna = Signal.RED;
merusak;
}
}
String publik keString() {
return "Lampu lalu lintas adalah" + warna;
}
public static void main(String[] args) {
TrafficLight t = TrafficLight baru();
untuk(int saya = 0; saya < 7; saya++) {
cetak(t);
t.perubahan();
}
}
} /* Keluaran:
Lampu lalu lintas berwarna MERAH
Lampu lalu lintas berwarna HIJAU
Lampu lalu lintas berwarna KUNING
Lampu lalu lintas berwarna MERAH
Lampu lalu lintas berwarna HIJAU
Lampu lalu lintas berwarna KUNING
Lampu lalu lintas berwarna MERAH
*///:~
Rahasia nilai() Meskipun kita menggunakan metode nilai sebelumnya, jika kita melihat Enum, kita tidak menemukan metode nilai. Jadi, apakah ada metode tersembunyi lainnya? Kita dapat memeriksanya dengan kode refleksi sederhana:
Copy kode kodenya sebagai berikut:
//: disebutkan/Refleksi.java
// Menganalisis enum menggunakan refleksi.
import java.lang.reflect.*;
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
enum Jelajahi { DI SINI, DI SANA }
Refleksi kelas publik {
public static Set<String> analisa(Kelas<?> enumClass) {
print("----- Menganalisis " + enumClass + " -----");
print("Antarmuka:");
untuk(Ketik t : enumClass.getGenericInterfaces())
cetak(t);
print("Dasar: " + enumClass.getSuperclass());
print("Metode : ");
Metode Set<String> = TreeSet<String>();
untuk(Metode m : enumClass.getMethods())
metode.tambahkan(m.getName());
mencetak(metode);
metode pengembalian;
}
public static void main(String[] args) {
Set<String> exploreMethods = analisa(Jelajahi.kelas);
Set<String> enumMethods = analisa(Enum.kelas);
print("Jelajahi.berisiSemua(Enum)? " +
exploreMethods.containsAll(enumMethods));
printnb("Jelajahi.removeAll(Enum): ");
exploreMethods.removeAll(enumMethods);
cetak(eksplorasiMetode);
// Dekompilasi kode untuk enum:
OSExecute.command("javap Jelajahi");
}
} /* Keluaran:
----- Menganalisis kelas Jelajahi -----
Antarmuka:
Basis: kelas java.lang.Enum
Metode:
[bandingkanTo, sama dengan, getClass, getDeclaringClass, kode hash, nama, beri tahu, beri tahuSemua, ordinal, toString, valueOf, nilai, tunggu]
----- Menganalisis kelas java.lang.Enum -----
Antarmuka:
java.lang.Sebanding<E>
antarmuka java.io.Serializable
Basis: kelas java.lang.Object
Metode:
[bandingkanTo, sama dengan, getClass, getDeclaringClass, kode hash, nama, beri tahu, beri tahuSemua, ordinal, toString, valueOf, tunggu]
Jelajahi.berisiSemua(Enum)?
Jelajahi.removeAll(Enum): [nilai]
Dikompilasi dari "Refleksi.java"
kelas terakhir Jelajahi diperluas java.lang.Enum{
final statis publik Jelajahi DI SINI;
final statis publik Jelajahi DI SANA;
penjelajahan akhir statis publik[] nilai();
public static Jelajahi valueOf(java.lang.String);
statis {};
}
*///:~
Kita dapat melihat bahwa metode nilai ditambahkan oleh kompiler. Metode valueOf juga ditambahkan oleh compiler saat membuat enumerasi, tetapi ada juga metode valueOf di kelas Enum, tetapi metode ini memiliki dua parameter, sedangkan metode valueOf yang ditambahkan oleh compiler hanya memiliki satu parameter. Pencacahan ditafsirkan sebagai final oleh kompiler, sehingga pencacahan tidak dapat diwariskan. Karena metode nilai adalah metode statis yang ditambahkan oleh kompiler, jika Anda memasukkan enumerasi ke Enum, metode nilai tidak akan tersedia, tetapi ada metode getEnumConstants di Kelas, jadi meskipun metode nilai adalah tidak tersedia di Enum , tetapi Anda masih bisa mendapatkan instance enumerasi melalui objek Class:
Copy kode kodenya sebagai berikut:
//: disebutkan/UpcastEnum.java
// Tidak ada metode nilai() jika Anda melakukan upcast enum
enum Pencarian { KE SINI, YON }
kelas publik UpcastEnum {
public static void main(String[] args) {
Pencarian[] vals = Pencarian.nilai();
Enum e = Cari.HITHER; // Upcast
// e.values(); // Tidak ada nilai() di Enum
untuk(Enum dan : e.getClass().getEnumConstants())
Sistem.keluar.println(en);
}
} /* Keluaran:
KE SINI
YON
*///:~
Implementasi tanpa pewarisan Karena tipe enumerasi yang kami definisikan semuanya mewarisi dari java.lang.Enum, dan Java tidak mendukung pewarisan berganda, jadi enumerasi tidak dibuat melalui pewarisan, tetapi enumerasi dapat dibuat dengan mewarisi satu atau lebih antarmuka:
Copy kode kodenya sebagai berikut:
//: enumerasi/kartun/EnumImplementation.java
// Enum dapat mengimplementasikan antarmuka
paket yang disebutkan.kartun;
import java.util.*;
import net.mindview.util.*;
enum CartoonCharacter mengimplementasikan Generator<CartoonCharacter> {
SLAPPY, SPANKY, PUNCHY, SILLY, BOUNCY, NUTTY, BOB;
swasta Random Rand = new Random(47);
Karakter Kartun publik selanjutnya() {
mengembalikan nilai()[rand.nextInt(nilai().panjang)];
}
}
Implementasi Enum kelas publik {
public static <T> void printNext(Generator<T> rg) {
Sistem.keluar.cetak(rg.next() + ", ");
}
public static void main(String[] args) {
// Pilih instance mana pun:
KartunKarakter cc = KartunKarakter.BOB;
untuk(int saya = 0; saya < 10; saya++)
printBerikutnya(cc);
}
} /* Keluaran:
BOB, PUNCHY, BOB, SPANKY, NUTTY, PUNCHY, SLAPPY, NUTTY, NUTTY, SLAPPY,
*///:~
Seleksi Acak Dalam banyak contoh kita nanti, kita akan memilih objek secara acak dari contoh enumerasi. Kita membuat kelas publik untuk mengimplementasikan ini:
Copy kode kodenya sebagai berikut:
//: net/mindview/util/Enums.java
paket net.mindview.util;
import java.util.*;
Enum kelas publik {
private static Random Rand = new Random(47);
public static <T extends Enum<T>> T acak(Kelas<T> ec) {
kembali acak(ec.getEnumConstants());
}
public static <T> T acak(nilai T[]) {
mengembalikan nilai[rand.nextInt(nilai.panjang)];
}
} ///:~
Copy kode kodenya sebagai berikut:
//: disebutkan/RandomTest.java
import net.mindview.util.*;
enum Aktivitas { DUDUK, BERBOHONG, BERDIRI, MELOMPAT, BERLARI, MENGHINDARI, LOMPAT, JATUH, TERBANG }
Tes Acak kelas publik {
public static void main(String[] args) {
untuk(int saya = 0; saya < 20; saya++)
System.out.print(Enums.random(Aktivitas.kelas) + " ");
}
} /* Keluaran:
BERDIRI TERBANG BERJALAN BERDIRI BERJALAN BERDIRI BERBARING MENGHINDARI DUDUK BERJALAN BERLOMPAP BERLOMPAP BERJALAN BERDIRI BERBARING JATUH BERJALAN TERBANG TERBANG BERBOHONG
*///:~
Penggunaan antarmuka untuk mengatur enumerasi tidak dapat diwariskan, yang terkadang menyebabkan ketidaknyamanan bagi kami, karena terkadang kami ingin menambah jumlah enumerasi melalui pewarisan, dan terkadang kami perlu mengelompokkan enumerasi. Untuk yang terakhir, kita dapat mendefinisikan enumerasi yang dikelompokkan dalam antarmuka, dan kemudian membuat enumerasi dengan mewarisi dari antarmuka ini Sebagai berikut, kita memiliki kategori makanan berbeda yang perlu dibuat sebagai enumerasi, namun kita perlu mendefinisikan setiap kategori sebagai Jenisnya. Pangan adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
//: disebutkan/menu/Makanan.java
// Subkategorisasi enum dalam antarmuka.
paket enumerasi.menu;
antarmuka publik Makanan {enum Appetizer mengimplementasikan Makanan {SALAD, SOUP, SPRING_ROLLS;}
enum MainCourse mengimplementasikan Makanan {LASAGNE, BURRITO, PAD_THAI,LENTILS, HUMMOUS, VINDALOO;}
enum Dessert mengimplementasikan Makanan {TIRAMISU, GELATO, BLACK_FOREST_CAKE,FRUIT, CREME_CARAMEL;}
enum Kopi mengimplementasikan Makanan {BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,LATTE, CAPPUCCINO, TEA, HERB_TEA;}
} ///:~
Karena setiap pencacahan didefinisikan sebagai implementasi antarmuka, setiap pencacahan bertipe Makanan, sebagai berikut:
Copy kode kodenya sebagai berikut:
//: disebutkan/menu/TypeOfFood.java
paket enumerasi.menu;
import static enumerasi.menu.Makanan.*;
kelas publik TypeOfFood {
public static void main(String[] args) {
Makanan makanan = Pembuka.SALAD;
makanan = Hidangan Utama.LASAGNE;
makanan = Makanan penutup.GELATO;
makanan = Kopi.CAPPUCCINO;
}
} ///:~
Namun antarmuka tidak dapat beroperasi pada beberapa tipe seperti enumerasi, jadi jika Anda memerlukan enumerasi, Anda dapat merangkum sebuah instance dari setiap jenis enumerasi dalam sebuah enumerasi:
Copy kode kodenya sebagai berikut:
//: disebutkan/menu/Kursus.java
paket enumerasi.menu;
import net.mindview.util.*;
kursus enum publik {
APPETIZER(Makanan.Makanan Pembuka.kelas),KURSUS UTAMA(Makanan.MainCourse.kelas),DESSERT(Makanan.Makanan penutup.kelas),KOPI(Makanan.Kopi.kelas);
nilai-nilai Food[] pribadi;
Kursus privat(Kelas<? extends Makanan> jenis) {
nilai = jenis.getEnumConstants();
}
Makanan publik randomSelection() {
return Enums.random(nilai);
}
} ///:~
Setiap enumerasi menggunakan objek Class sebagai parameter konstruktor yang sesuai. Kita dapat menggunakan getEnumConstants dari parameter ini untuk mendapatkan instance enumerasi. Contoh ini dapat digunakan dalam metode randomSelection untuk menghasilkan makanan acak:
Copy kode kodenya sebagai berikut:
//: disebutkan/menu/Meal.java
paket enumerasi.menu;
Makanan kelas umum {
public static void main(String[] args) {
untuk(int saya = 0; saya < 5; saya++) {
for(Mata kuliah : Kursus.nilai()) {
Makanan makanan = kursus.randomSelection();
System.out.println(makanan);
}
Sistem.keluar.println("---");
}
}
} /* Keluaran:
SPRING_ROLLS
VINDALOO
BUAH
DECAF_COFFEE
---
SUP
VINDALOO
BUAH
TEH
---
SALAD
BURRITO
BUAH
TEH
---
SALAD
BURRITO
CREME_KARAMEL
TERBARU
---
SUP
BURRITO
TIRAMISU
ESPRESSO
---
*///:~
Berikut implementasi yang lebih ringkas:
Copy kode kodenya sebagai berikut:
//: disebutkan/SecurityCategory.java
// Subkategorisasi enum yang lebih ringkas.
import net.mindview.util.*;
enum Kategori Keamanan {
SAHAM(Security.Stock.class), OBLIGASI(Security.Bond.class);
Nilai keamanan[];
SecurityCategory(Kelas<? extends Security> jenis) {
nilai = jenis.getEnumConstants();
}
keamanan antarmuka {
enum Stock mengimplementasikan Keamanan { SHORT, LONG, MARGIN }
enum Bond menerapkan Keamanan { KOTA, SAMPAH }
}
Keamanan publik randomSelection() {
return Enums.random(nilai);
}
public static void main(String[] args) {
untuk(int saya = 0; saya < 10; saya++) {
Kategori SecurityCategory = Enums.random(SecurityCategory.class);
System.out.println(kategori + ": " +
kategori.randomSelection());
}
}
} /* Keluaran:
OBLIGASI: KOTA
OBLIGASI: KOTA
SAHAM: MARGIN
SAHAM: MARGIN
OBLIGASI: SAMPAH
SAHAM: PENDEK
STOCK: PANJANG
STOCK: PANJANG
OBLIGASI: KOTA
OBLIGASI: SAMPAH
*///:~
Copy kode kodenya sebagai berikut:
//: disebutkan/menu/Meal2.java
paket enumerasi.menu;
import net.mindview.util.*;
enum publik Makanan2 {
APPETIZER(Makanan.Makanan Pembuka.kelas),KURSUS UTAMA(Makanan.MainCourse.kelas),DESSERT(Makanan.Makanan penutup.kelas),KOPI(Makanan.Kopi.kelas);
nilai-nilai Food[] pribadi;
private Meal2(Kelas<? extends Makanan> jenis) {
nilai = jenis.getEnumConstants();
}
antarmuka publik Makanan {
enum Appetizer mengimplementasikan Makanan {SALAD, SOUP, SPRING_ROLLS;}
enum MainCourse mengimplementasikan Makanan {LASAGNE, BURRITO, PAD_THAI,LENTILS, HUMMOUS, VINDALOO;}
enum Dessert mengimplementasikan Makanan {TIRAMISU, GELATO, BLACK_FOREST_CAKE,FRUIT, CREME_CARAMEL;}
enum Kopi mengimplementasikan Makanan {BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,LATTE, CAPPUCCINO, TEA, HERB_TEA;}
}
Makanan publik randomSelection() {
return Enums.random(nilai);
}
public static void main(String[] args) {
untuk(int saya = 0; saya < 5; saya++) {
for(Makanan2 makanan : Makanan2.nilai()) {
Makanan makanan = makan.randomSelection();
System.out.println(makanan);
}
Sistem.keluar.println("---");
}
}
} /* Outputnya sama dengan Meal.java *///:~
Gunakan EnumSet alih-alih flag EnumSet telah ditambahkan di Java SE5 untuk menggabungkan enum dan Set untuk menggantikan flag bit berbasis bilangan bulat. Bendera bit biasanya digunakan untuk menunjukkan peralihan suatu jenis informasi, tetapi dalam kode, bit dioperasikan daripada konsep yang bermakna, sehingga tidak mudah untuk dipahami. EnumSet lebih cepat daripada flag bit. Ia menggunakan long secara internal untuk merepresentasikan vektor bit, dan kemudian Anda dapat menggunakan bahasa yang lebih konseptual untuk merepresentasikan peralihan bit tertentu tanpa mengkhawatirkan efisiensi. Elemen dalam EnumSet harus berasal dari enumerasi yang sama. Berikut ini definisi enumerasi posisi alarm:
Copy kode kodenya sebagai berikut:
//: disebutkan/AlarmPoints.java
paket disebutkan;
public enum AlarmPoints {STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, KAMAR MANDI, UTILITAS, DAPUR} ///:~
Kemudian gunakan kelas EnumSet untuk melacak status alarm:
Copy kode kodenya sebagai berikut:
//: disebutkan/EnumSets.java
// Operasi pada EnumSet
paket disebutkan;
import java.util.*;
import static enumerasi.AlarmPoints.*;
import static net.mindview.util.Print.*;
EnumSet kelas publik {
public static void main(String[] args) {
EnumSet<AlarmPoints> poin = EnumSet.noneOf(AlarmPoints.class); // Kumpulan kosong
points.add(KAMAR MANDI);
mencetak(poin);
points.addAll(EnumSet.of(STAIR1, STAIR2, DAPUR));
mencetak(poin);
poin = EnumSet.allOf(AlarmPoints.class);
points.removeAll(EnumSet.of(STAIR1, STAIR2, DAPUR));
mencetak(poin);
points.removeAll(EnumSet.range(OFFICE1, OFFICE4));
mencetak(poin);
poin = EnumSet.complementOf(poin);
mencetak(poin);
}
} /* Keluaran:
[KAMAR MANDI]
[TANGGA 1, TANGGA 2, KAMAR MANDI, DAPUR]
[LOBI, KANTOR1, KANTOR2, KANTOR3, KANTOR4, KAMAR MANDI, UTILITAS]
[LOBI, KAMAR MANDI, UTILITAS]
[TANGGA1, TANGGA2, KANTOR1, KANTOR2, KANTOR3, KANTOR4, DAPUR]
*///:~
EnumSet dibangun dengan tipe panjang dan memiliki 64 bit, lalu bagaimana jika tipe enumerasi kita melebihi angka ini?
Copy kode kodenya sebagai berikut:
//: disebutkan/BigEnumSet.java
import java.util.*;
kelas publik BigEnumSet {
enum Besar { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,A22, A23 , A24, A25, A26, A27, A28, A29, A30, A31, A32,
A33, A34, A35, A36, A37, A38, A39, A40, A41, A42, A43,A44, A45, A46, A47, A48, A49, A50, A51, A52, A53, A54,A55, A56, A57, A58, A59, A60, A61, A62, A63, A64, A65,
A66, A67, A68, A69, A70, A71, A72, A73, A74, A75}
public static void main(String[] args) {
EnumSet<Besar> bigEnumSet = EnumSet.allOf(Besar.kelas);
Sistem.keluar.println(bigEnumSet);
}
} /* Keluaran:
[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24 , A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40, A41, A42, A43, A44, A45, A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, A60, A61, A62, A63, A64, A65, A66, A67, A68, A69, A70, A71, A72, A73, A74, A75]
*///:~
Kita dapat melihat bahwa program berjalan normal, sehingga kemungkinan besar telah ditambahkan tipe panjang secara internal untuk membantu mengakomodasi tipe enumerasi menggunakan EnumMap.
EnumMap adalah tipe khusus dari Map. Nilai kuncinya hanya dapat berupa tipe dalam enumerasi yang sama. Oleh karena itu, EnumMap dapat diimplementasikan secara internal melalui array, yang sangat efisien.
Copy kode kodenya sebagai berikut:
//: disebutkan/EnumMaps.java
// Dasar-dasar EnumMaps.
paket disebutkan;
import java.util.*;
import static enumerasi.AlarmPoints.*;
import static net.mindview.util.Print.*;
antarmuka Perintah { tindakan batal();
EnumMaps kelas publik {
public static void main(String[] args) {
EnumMap<AlarmPoints,Command> em = EnumMap<AlarmPoints,Command>(AlarmPoints.class) baru;
em.put(DApur, Perintah baru() {
public void action() { print("Dapur terbakar!");
});
em.put(KAMAR MANDI, Perintah baru() {
public void action() { print("Peringatan kamar mandi!");
});
for(Map.Entry<AlarmPoints,Command> e : em.entrySet()) {
printnb(e.getKey() + ": ");
e.getValue().action();
}
try { // Jika tidak ada nilai untuk kunci tertentu:
em.mendapatkan(UTILITAS).aksi();
} tangkapan(Pengecualian e) {
cetak(e);
}
}
} /* Keluaran:
KAMAR MANDI: Peringatan kamar mandi!
DAPUR: Kebakaran dapur!
java.lang.NullPointerException
*///:~
Metode konstanta spesifik Pencacahan Java memiliki fitur yang sangat menarik, yaitu, perilaku berbeda dapat ditentukan untuk setiap contoh pencacahan, Untuk mencapai hal ini, kami mendefinisikan satu atau lebih metode abstrak sebagai bagian dari pencacahan, dan kemudian menentukan perilaku berbeda untuk masing-masing metode. contoh pencacahan. Metode definisi contoh pencacahan:
Copy kode kodenya sebagai berikut:
//: disebutkan/ConstantSpecificMethod.java
import java.util.*;
import java.teks.*;
public enum ConstantSpecificMethod {
DATE_TIME {String getInfo() {return DateFormat.getDateInstance().format(new Date());}},
CLASSPATH {String getInfo() {return System.getenv("CLASSPATH");}},
VERSI {String getInfo() {return System.getProperty("java.version");}};
string abstrak getInfo();
public static void main(String[] args) {
for(ConstantSpecificMethod csm : nilai())
Sistem.keluar.println(csm.getInfo());
}
} /* (Jalankan untuk melihat keluaran) *///:~
Kode di atas tampaknya terjebak bahwa setiap elemen enumerasi adalah elemen yang berbeda, dan semua elemen mewarisi dari kelas dasar ConstantSpecificMethod, tetapi kita tidak dapat memahaminya dengan cara ini, karena kita tidak dapat memperlakukan elemen enumerasi sebagai tipe:
Copy kode kodenya sebagai berikut:
//: disebutkan/NotClasses.java
// {Jalankan: javap -c LikeClasses}
import static net.mindview.util.Print.*;
enum LikeClasses {WINKEN { void behavior() { print("Behavior1"); ;
perilaku batal abstrak();
}
kelas publik BukanKelas {
// void f1(contoh LikeClasses.WINKEN) {} // Tidak
} /* Keluaran:
Dikompilasi dari "NotClasses.java"
kelas abstrak LikeClasses meluas java.lang.Enum{
LikeClasses akhir statis publik WINKEN;
LikeClasses final statis publik BLINKEN;
LikeClasses akhir statis publik NOD;
...
*///:~
Perhatikan contoh lainnya. Ada menu cuci mobil. Pelanggan memilih layanan yang berbeda berdasarkan menu yang berbeda. Anda dapat menggunakan metode konstan tertentu untuk mengaitkan menu dengan layanan, dan menggunakan EnumSet untuk mempertahankan pilihan pelanggan, sebagai berikut:
Copy kode kodenya sebagai berikut:
//: disebutkan/CarWash.java
import java.util.*;
import static net.mindview.util.Print.*;
Pencucian Mobil kelas umum {
public enum Cycle {BAGIAN BAWAH {void action() { print("Menyemprot bagian bawah bodi mobil" }},
WHEELWASH {void action() { print("Mencuci roda" }},
PREWASH {void action() { print("Melonggarkan kotoran" }},
DASAR {void action() { print("Pencucian dasar" }},
HOTWAX {void action() { print("Mengoleskan lilin panas" }},
BILAS {void action() { print("Membilas" }},
BLOWDRY {void action() { print("Meniup kering" }};
tindakan batal abstrak();
}
EnumSet<Cycle> cycles = EnumSet.of(Cycle.BASIC, Cycle.RINSE);
public void add(Siklus siklus) { cycles.add(cycle);
public void cuciMobil() {
for(Siklus c : siklus)
c.aksi();
}
String publik toString() { return cycles.toString();
public static void main(String[] args) {
Cuci Mobil = Cuci Mobil baru();
mencetak(mencuci);
cuci.cuciMobil();
// Urutan penambahan tidak penting:
cuci.tambahkan(Siklus.BLOWDRY);
wash.add(Cycle.BLOWDRY); // Duplikat diabaikan
cuci.tambahkan(Siklus.BILAS);
cuci.tambahkan(Siklus.HOTWAX);
mencetak(mencuci);
cuci.cuciMobil();
}
} /* Keluaran:
[DASAR, BILAS]
Pencucian dasar
Membilas
[DASAR, LILIN PANAS, BILAS, PENGERINGAN]
Pencucian dasar
Menerapkan lilin panas
Membilas
Meniup kering
*///:~
Kita juga dapat mengganti metode konstanta spesifik default daripada menggunakan metode abstrak yang diwariskan, sebagai berikut:
Copy kode kodenya sebagai berikut:
//: disebutkan/OverrideConstantSpecific.java
import static net.mindview.util.Print.*;
enum publik OverrideConstantSpecific {
NUT, BOLT,WASHER {void f() { print("Metode yang diganti" }};
void f() { print("perilaku default");
public static void main(String[] args) {
for(OverrideConstantSpecific ocs : nilai()) {
printnb(ocs + ": ");
ocs.f();
}
}
} /* Keluaran:
NUT: perilaku default
BOLT: perilaku default
WASHER: Metode yang diganti
*///:~
Terkadang kita ingin meneruskan permintaan tertentu dalam rantai. Mengetahui bahwa suatu objek dalam rantai dapat menangani permintaan tersebut dapat dengan mudah dicapai dengan menggunakan metode konstan tertentu.
Copy kode kodenya sebagai berikut:
//: disebutkan/PostOffice.java
// Memodelkan kantor pos.
Jenis yang Dihitung 743
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
kelas Surat {
// NO menurunkan kemungkinan pemilihan acak:
enum Pengiriman Umum {YA,NO1,NO2,NO3,NO4,NO5}
enum Kemampuan Pemindaian {TIDAK DAPAT DIPILIH,YES1,YES2,YES3,YES4}
enum Keterbacaan {ILLEGIBLE,YES1,YES2,YES3,YES4}
enum Alamat {SALAH,OK1,OK2,OK3,OK4,OK5,OK6}
enum Alamat Pengembalian {HILANG,OK1,OK2,OK3,OK4,OK5}
Pengiriman Umum Pengiriman umum;
kemampuan pemindaian kemampuan pemindaian;
Keterbacaan keterbacaan;
Alamat alamat;
Alamat Pengembalian alamat Pengembalian;
penghitung panjang statis = 0;
id panjang = penghitung++;
string publik toString() { kembalikan "Email " + id;
detail String publik() {
return toString() + ", Pengiriman Umum: " + generalDelivery + ", Keterbacaan Alamat: " + keterbacaan + ", Keterbacaan Alamat: " + keterbacaan +
", Alamat Alamat:" + alamat + ", Alamat pengirim:" + alamat kembali;
}
//Buat Surat percobaan:
Email statis publik randomMail() {
Surat m = Surat baru();
m.generalDelivery= Enums.random(GeneralDelivery.class);
m.scannability = Enums.random(Scannability.class);
m.keterbacaan = Enums.random(Keterbacaan.kelas);
m.alamat = Enums.random(Alamat.kelas);
m.returnAddress = Enums.random(ReturnAddress.kelas);
kembalikan m;
}
public static Iterable<Mail> generator(jumlah int akhir) {
kembalikan Iterable<Mail>() baru {
int n = hitung;
Iterator publik<Mail> iterator() {
kembalikan Iterator baru<Mail>() {
boolean publik hasNext() { kembalikan n-- > 0;
Surat publik berikutnya() { kembalikan RandomMail();
public void hapus() {// Tidak diterapkan
melempar UnsupportedOperationException();
}
};
}
};
}
}
Kantor Pos kelas publik {
enum MailHandler {
UMUM_PENGIRIMAN {
pegangan boolean(Mail m) {
switch(m.generalDelivery) {
kasus YA:
print("Menggunakan pengiriman umum untuk " + m);
kembali benar;
default: mengembalikan salah;
}
}
},
MESIN_PINDAI {
pegangan boolean(Mail m) {
beralih(m.kemampuan pemindaian) {
case TIDAK DAPAT DIPILIH: return false;
bawaan:
beralih(alamat m) {
case SALAH: return false;
bawaan:
print("Mengirimkan "+m+" secara otomatis");
kembali benar;
}
}
}
},
VISUAL_INSPEKSI {
pegangan boolean(Mail m) {
beralih(m.keterbacaan) {
kasus TIDAK BISA DIGUNAKAN: return false;
bawaan:
beralih(alamat m) {
case SALAH: return false;
bawaan:
print("Pengiriman " + m + " secara normal");
kembali benar;
}
}
}
},
RETURN_TO_SENDER {
pegangan boolean(Mail m) {
switch(m.returnAddress) {
kasus HILANG: return false;
bawaan:
print("Mengembalikan "+m+" ke pengirim");
kembali benar;
}
}
};
pegangan boolean abstrak(Mail m);
}
pegangan kekosongan statis (Mail m) {
untuk(penangan MailHandler : MailHandler.values())
if(penangan.pegangan(m))
kembali;
print(m+" adalah huruf mati");
}
public static void main(String[] args) {
for(Surat surat : Mail.generator(10)) {
print(mail.detail());
menangani (surat);
mencetak("*****");
}
}
} /* Keluaran:
Surat 0, Pengiriman Umum: NO2, Kemampuan Pemindaian Alamat: TIDAK DAPAT DIPINCI, Keterbacaan Alamat: YES3, Alamat Alamat: OK1, Alamat pengirim: OK1
Mengirimkan Mail 0 secara normal
*****
Surat 1, Pengiriman Umum: NO5, Keterbacaan Alamat: YA3, Keterbacaan Alamat: TIDAK DAPAT DIGUNAKAN, Alamat Alamat: OK5, Alamat pengirim: OK1
Mengirimkan Surat 1 secara otomatis
*****
Surat 2, Pengiriman Umum: YA, Keterbacaan Alamat: YES3, Keterbacaan Alamat: YES1, Alamat Alamat: OK1, Alamat pengirim: OK5
Menggunakan pengiriman umum untuk Mail 2
*****
Surat 3, Pengiriman Umum: NO4, Keterbacaan Alamat: YES3, Keterbacaan Alamat: YES1, Alamat Alamat: SALAH, Alamat pengirim: OK4
Mengembalikan Mail 3 ke pengirim
*****
Surat 4, Pengiriman Umum: NO4, Kemampuan Pemindaian Alamat: TIDAK DAPAT DIPINCI, Keterbacaan Alamat: YA1, Alamat Alamat: SALAH, Alamat pengirim: OK2
Mengembalikan Mail 4 ke pengirim
*****
Surat 5, Pengiriman Umum: NO3, Keterbacaan Alamat: YA1, Keterbacaan Alamat: TIDAK DAPAT DIGUNAKAN, Alamat Alamat: OK4, Alamat pengirim: OK2
Mengirimkan Mail 5 secara otomatis
*****
Surat 6, Pengiriman Umum: YA, Keterbacaan Alamat: YES4, Keterbacaan Alamat: TIDAK DAPAT DIGUNAKAN, Alamat Alamat: OK4, Alamat pengirim: OK4
Menggunakan pengiriman umum untuk Mail 6
*****
Surat 7, Pengiriman Umum: YA, Keterbacaan Alamat: YES3, Keterbacaan Alamat: YES4, Alamat Alamat: OK2, Alamat pengirim: HILANG
Menggunakan pengiriman umum untuk Mail 7
*****
Surat 8, Pengiriman Umum: NO3, Keterbacaan Alamat: YES1, Keterbacaan Alamat: YES3, Alamat Alamat: SALAH, Alamat pengirim: HILANG
Mail 8 adalah surat mati
*****
Mail 9, Pengiriman Umum: NO1, Alamat Dapat Dipindai: TIDAK DAPAT DIPINCI, Keterbacaan Alamat: YES2, Alamat Alamat: OK1, Alamat pengirim: OK4
Mengirimkan Mail 9 secara normal
*****
*///:~
Tipe enumerasi juga merupakan tipe ideal untuk membuat mesin keadaan. Mesin keadaan dapat berpindah di antara sejumlah keadaan sesuai dengan masukannya, dan kemudian mengakhiri pekerjaannya setelah keadaan tertentu terpenuhi keluaran yang sesuai. Mesin penjual otomatis adalah contoh mesin negara yang umum di mana kita mendefinisikan masukan yang berbeda dalam suatu pencacahan:
Copy kode kodenya sebagai berikut:
//: disebutkan/Input.java
paket disebutkan;
import java.util.*;
Masukan enum publik {
NIKEL(5), DIME(10), QUARTER(25), DOLAR(100),PASANG GIGI(200), CHIPS(75), SODA(100), SOAP(50),ABORT_TRANSACTION {
public int amount() {//Larang
throw new RuntimeException("ABORT.jumlah()");
}
},
STOP {/ // Ini harus menjadi contoh terakhir.
public int amount() {//Larang
melempar RuntimeException baru("SHUT_DOWN.amount()");
}
};
nilai int; // Dalam sen
Masukan(nilai int) { ini.nilai = nilai }
Masukan() {}
int jumlah() { nilai kembalian; }; // Dalam sen
statis Acak Rand = Acak baru (47);
masukan statis publik randomSelection() {
// Jangan sertakan STOP:
mengembalikan nilai()[rand.nextInt(nilai().panjang - 1)];
}
} ///:~
VendingMachine digunakan untuk merespons masukan. Pertama, ia mengklasifikasikan masukan melalui enumerasi Kategori, lalu menggunakan pernyataan switch:
Copy kode kodenya sebagai berikut:
//: disebutkan/VendingMachine.java
// {Args: VendingMachineInput.txt}
paket disebutkan;
import java.util.*;
import net.mindview.util.*;
import static enumerasi.Input.*;
import static net.mindview.util.Print.*;
enum Kategori {
UANG(NICKEL, DIME, QUARTER, DOLLAR),ITEM_SELECTION(TOOTHPASTE, CHIPS, SODA, SOAP),QUIT_TRANSACTION(ABORT_TRANSACTION),SHUT_DOWN(STOP);
nilai Input[] pribadi;
Kategori(Masukan... jenis) { nilai = jenis }
kategori EnumMap<Input,Category> statis pribadi = EnumMap baru<Input,Category>(Input.class);
statis {
for(Kategori c : Kategori.kelas.getEnumConstants())
for(Jenis masukan : c.nilai)
kategori.put(tipe, c);
}
Kategori kategori statis publik mengkategorikan(Masukan masukan) {
kembalikan kategori.dapatkan(input);
}
}
Mesin Penjual Otomatis kelas publik {
keadaan statis pribadi keadaan = Keadaan.RESTING;
jumlah int statis pribadi = 0;
pemilihan Input statis pribadi = null;
enum StateDuration {TRANSIENT} //Menandai enum
enum Negara {
BERISTIRAHAT {
batal selanjutnya(Masukkan masukan) {
switch(Kategori.kategorikan(masukan)) {
kasus UANG:
jumlah += masukan.jumlah();
negara = TAMBAH_UANG;
merusak;
kasus SHUT_DOWN:
negara = TERMINAL;
bawaan:
}
}
},
TAMBAH_UANG {
batal berikutnya(Masukkan masukan) {
switch(Kategori.kategorikan(masukan)) {
kasus UANG:
jumlah += masukan.jumlah();
merusak;
kasus ITEM_SELECTION:
pilihan = masukan;
if(jumlah < pilihan.jumlah())
print("Uang tidak cukup untuk "+pilihan);
else state = DISPENSING;
merusak;
kasus QUIT_TRANSACTION:
negara = GIVING_CHANGE;
merusak;
kasus SHUT_DOWN:
negara = TERMINAL;
bawaan:
}
}
},
DISPENSING(StateDuration.TRANSIEN) {
batal selanjutnya() {
print("Inilah pilihan Anda" +);
jumlah -= pilihan.jumlah();
negara = GIVING_CHANGE;
}
},
GIVING_CHANGE(StateDuration.TRANSIENT) {
batal selanjutnya() {
jika(jumlah > 0) {
print("Uang kembalian Anda : "+jumlah);
jumlah = 0;
}
keadaan = BERISTIRAHAT;
}
},
TERMINAL { batal keluaran() { print("Dihentikan");
boolean pribadi isTransient = false;
Negara() {}
Negara(StateDuration trans) { isTransient = benar;
batal berikutnya(Masukkan masukan) {
throw new RuntimeException("Hanya panggil " + "berikutnya(Masukan input) untuk status non-sementara");
}
batal selanjutnya() {
throw new RuntimeException("Hanya panggil next() untuk " + "StateDuration.TRANSIENT States");
}
batal keluaran() { cetak(jumlah }
}
run void statis(Generator<Input> gen) {
while(negara bagian != Negara.TERMINAL) {
negara.next(gen.next());
while(state.isTransient)
negara.berikutnya();
negara.output();
}
}
public static void main(String[] args) {
Generator<Input> gen = new RandomInputGenerator();
if(args.panjang == 1)
gen = FileInputGenerator baru(args[0]);
lari(gen);
}
}
// Untuk pemeriksaan kewarasan dasar:
kelas RandomInputGenerator mengimplementasikan Generator<Input> {
Masukan publik berikutnya() { kembalikan Masukan.randomSelection();
}
// Membuat Input dari file string yang dipisahkan ';':
kelas FileInputGenerator mengimplementasikan Generator<Input> {
masukan Iterator<String> pribadi;
FileInputGenerator publik(String nama file) {
masukan = File Teks baru(Namafile, ";").iterator();
}
Masukan publik selanjutnya() {
if(!input.hasNext())
kembalikan nol;
return Enum.valueOf(Input.kelas, input.next().trim());
}
} /* Keluaran:
ini CHIPS Anda
ini pasta gigimu
Perubahan Anda: 35
Uang tidak cukup untuk SODA
Uang tidak cukup untuk SODA
Perubahan Anda: 75
Dihentikan
*///:~
Berikut adalah data pengujian yang digunakan untuk menghasilkan keluaran di atas:
Copy kode kodenya sebagai berikut:
KUARTAL;
DOLAR;
KUARTAL;
KUARTAL;
KUARTAL;
ABORT_TRANSAKSI;
BERHENTI;
///:~
Pembongkaran ganda Ketika berhadapan dengan interaksi antara beberapa tipe, kodenya cenderung menjadi berantakan, seperti Number.plush(Number), Number.mutiply(Number), dll. Number hanyalah kelas dasar dari keluarga, jadi ketika Anda menelepon Ketika a.plus(b), Anda tidak mengetahui tipe a maupun tipe b, lalu bagaimana memastikan bahwa interaksi di antara keduanya sudah benar? Java hanya dapat melakukan pembongkaran tunggal, yaitu jika satu atau lebih operasi dari beberapa tipe yang tidak diketahui dilakukan, Java hanya dapat melakukan mekanisme pengikatan dinamis pada salah satu tipe tersebut, yang tidak dapat menyelesaikan masalah yang kita bicarakan di atas, jadi Anda punya untuk menulis kode pengikatan dinamis secara manual.
Solusinya adalah dengan menggunakan multibinding. Polimorfisme hanya dapat terjadi saat memanggil suatu metode, jadi jika Anda memerlukan beberapa pembongkaran, Anda harus memanggil beberapa metode. Dengan beberapa pembukaan bungkus, Anda harus memiliki metode virtual yang memanggil metode setiap jenis untuk membuka bungkusnya. Contoh berikut adalah contoh batu-kertas-gunting:
Copy kode kodenya sebagai berikut:
//: disebutkan/Hasil.java
paket disebutkan;
Hasil enum publik { MENANG, KALAH, DRAW } ///:~
//: disebutkan/RoShamBo1.java
// Demonstrasi beberapa pengiriman.
paket disebutkan;
import java.util.*;
import static enumerasi.Hasil.*;
antarmuka Barang {
Hasil bersaing(Item itu);
Evaluasi hasil(Kertas p);
Evaluasi hasil(Gunting);
Evaluasi hasil(Batu r);
}
kelas Makalah mengimplementasikan Item {
Hasil publik bersaing(Item itu) { kembalikan itu.eval(ini };
evaluasi Hasil publik (Kertas p) { return DRAW;
evaluasi Hasil publik (Gunting) { kembali MENANG;
evaluasi Hasil publik(Batu r) { kembali KALAH }
public String toString() { kembalikan "Kertas"; }
}
gunting kelas mengimplementasikan Item {
Hasil publik bersaing(Item itu) { kembalikan itu.eval(ini };
evaluasi Hasil publik (Kertas p) { return KALAH }
evaluasi Hasil publik (Gunting) { return DRAW }
evaluasi Hasil publik(Batu r) { kembali MENANG;
public String toString() { kembalikan "Gunting"; }
}
class Rock mengimplementasikan Item {
Hasil publik bersaing(Item itu) { kembalikan itu.eval(ini };
evaluasi Hasil publik (Makalah p) { kembali MENANG;
evaluasi Hasil publik(Gunting s) { kembali KALAH }
evaluasi Hasil publik(Batu r) { return DRAW }
String publik toString() { kembalikan "Batu"; }
}
kelas publik RoShamBo1 {
UKURAN int akhir statis = 20;
private static Random Rand = new Random(47);
Item statis publik newItem() {
beralih(rand.nextInt(3)) {
bawaan:
kasus 0: kembalikan Gunting baru();
kasus 1: kembalikan Kertas baru();
kasus 2: kembalikan Rock baru();
}
}
kecocokan kekosongan statis publik (Item a, Item b) {
System.out.println(a + " vs. " + b + ": " + a.compete(b));
}
public static void main(String[] args) {
untuk(int i = 0; i < UKURAN; i++)
cocok(Item baru(),Item baru());
}
} /* Keluaran:
Batu vs. Batu: GAMBAR
Kertas vs. Batu: MENANG
Kertas vs. Batu: MENANG
Kertas vs. Batu: MENANG
Gunting vs. Kertas: MENANG
Gunting vs. Gunting: GAMBAR
Gunting vs. Kertas: MENANG
Batu vs. Kertas: KALAH
Kertas vs. Kertas: GAMBAR
Batu vs. Kertas: KALAH
Kertas vs. Gunting: KALAH
Kertas vs. Gunting: KALAH
Batu vs. Gunting: MENANG
Batu vs. Kertas: KALAH
Kertas vs. Batu: MENANG
Gunting vs. Kertas: MENANG
Kertas vs. Gunting: KALAH
Kertas vs. Gunting: KALAH
Kertas vs. Gunting: KALAH
Kertas vs. Gunting: KALAH
*///:~
Kami menggunakan banyak metode untuk mencapai banyak pembongkaran, tetapi yang kami peroleh adalah struktur kode yang baik. Masalah terbesar saat menggunakan solusi enumerasi untuk mengimplementasikan kode di atas adalah instance enumerasi bukanlah suatu tipe, sehingga instance enumerasi tidak dapat digunakan sebagai tipe parameter. Tetapi kita masih dapat memiliki cara lain untuk mengatasi hambatan ini.
Copy kode kodenya sebagai berikut:
//: disebutkan/roshambo2.java
// Mengganti satu enum pada yang lain.
paket disebutkan;
Impor Static Enumerated.Outcome.*;
Publik enum roshambo2 mengimplementasikan pesaing <oshambo2> {
Kertas (gambar, kalah, menang), gunting (menang, menarik, kalah), rock (kalah, menang, menarik);
Vaper Hasil Pribadi, VScissors, Vrock;
Roshambo2 (kertas hasil, gunting hasil, hasil rock) {
this.vpaper = kertas;
this.vscissors = gunting;
this.vrock = rock;
}
Hasil publik bersaing (roshambo2 it) {
beralih (itu) {
bawaan:
Kertas kasus: return vpaper;
Gunting kasus: return vScissors;
Case Rock: return vrock;
}
}
public static void main(String[] args) {
Roshambo.Play (Roshambo2.class, 20);
}
} /* Output:
Rock vs. Rock: Draw
Gunting vs. Rock: Kehilangan
Gunting vs. Rock: Kehilangan
Jenis yang disebutkan 753
Gunting vs. Rock: Kehilangan
Kertas vs. gunting: kalah
Kertas vs. kertas: gambar
Kertas vs. gunting: kalah
Rock vs Gunting: Menang
Gunting vs Gunting: Draw
Rock vs Gunting: Menang
Gunting vs. Paper: Menang
Gunting vs. Paper: Menang
Rock vs. Paper: Kehilangan
Rock vs Gunting: Menang
Gunting vs. Rock: Kehilangan
Kertas vs. gunting: kalah
Gunting vs. Paper: Menang
Gunting vs. Paper: Menang
Gunting vs. Paper: Menang
Gunting vs. Paper: Menang
*///: ~
Copy kode kodenya sebagai berikut:
//: disebutkan/pesaing.java
// Mengganti satu enum pada yang lain.
paket disebutkan;
Pesaing antarmuka publik <T memperluas pesaing <t>> {
Hasil bersaing (T kompetitor);
} ///: ~
Copy kode kodenya sebagai berikut:
//: disebutkan/roshambo.java
// Alat Umum untuk Contoh Roshambo.
paket disebutkan;
impor net.mindview.util.*;
Roshambo kelas publik {
public static <t memperluas pesaing <t>> void match (t a, t b) {
System.out.println (a + "vs." + b + ":" + a.compete (b));
}
Public Static <T Extends Enum <T> & Pesaing <T>> void Play (kelas <T> rsbclass, ukuran int) {
untuk (int i = 0; i <size; i ++)
kecocokan (enums.random (rsbclass), enums.random (rsbclass));
}
} ///: ~
Karena merumuskan metode statis dapat memberikan metode yang berbeda untuk setiap jenis enumerasi, tampaknya merupakan solusi yang baik untuk mencapai beberapa pembongkaran, tetapi kami masih menghadapi masalah bahwa instance enumerasi bukanlah tipe, jadi yang bisa kami lakukan hanyalah menambahkan pernyataan sakelar :
Copy kode kodenya sebagai berikut:
//: disebutkan/roshambo3.java
// Menggunakan metode spesifik konstan.
paket disebutkan;
Impor Static Enumerated.Outcome.*;
Publik enum roshambo3 mengimplementasikan pesaing <oshambo3> {
KERTAS {
Hasil publik bersaing (roshambo3 it) {
beralih (itu) {
default: // untuk menempatkan kompiler
Kertas Kasus: Return Draw;
Gunting kasus: kalah kembali;
Case Rock: Return Win;
}
}
},
Gunting {
Hasil publik bersaing (roshambo3 it) {
beralih (itu) {
bawaan:
Kertas Kasus: Kembali Menang;
Gunting kasing: draw kembali;
Case Rock: Kembali Kalah;
}
}
},
BATU {
Hasil publik bersaing (roshambo3 it) {
beralih (itu) {
bawaan:
Kertas Kasus: Kembali Kalah;
Gunting kasus: Kembali menang;
Case Rock: Return Draw;
}
}
};
Hasil abstrak publik bersaing (roshambo3 it);
public static void main(String[] args) {
Roshambo.Play (Roshambo3.Class, 20);
}
}/ * Output yang sama seperti roshambo2.java * ///: ~
Kode berikut adalah metode implementasi yang lebih ringkas:
Copy kode kodenya sebagai berikut:
//: disebutkan/roshambo4.java
paket disebutkan;
Publik enum roshambo4 mengimplementasikan pesaing <oshambo4> {
BATU {
Hasil publik bersaing (lawan roshambo4) {
return compete (gunting, lawan);
}
},
Gunting {
Hasil publik bersaing (lawan roshambo4) {
return compete (kertas, lawan);
}
},
KERTAS {
Hasil publik bersaing (lawan roshambo4) {
return compete (rock, lawan);
}
};
Hasil Compete (Roshambo4 Loser, Roshambo4 Lawan) {
return ((lawan == this)? hasil.draw: ((lawan == pecundang)? Hasil.win: hasil.lose));
}
public static void main(String[] args) {
Roshambo.Play (Roshambo4.class, 20);
}
}/ * Output yang sama seperti roshambo2.java * ///: ~
Kelas Enummap tampaknya menjadi cara yang baik untuk benar -benar menerapkan beberapa pembongkaran:
Copy kode kodenya sebagai berikut:
//: disebutkan/roshambo5.java
// Beberapa pengiriman menggunakan enummap enummaps.
paket disebutkan;
import java.util.*;
Impor Static Enumerated.Outcome.*;
enum roshambo5 mengimplementasikan pesaing <oshambo5> {
Kertas, gunting, batu;
static enumumap <roshambo5, enummap <roshambo5, hasil >> table = enummap baru <roshambo5, enummap <roshambo5, hasil >> (roshambo5.class);
statis {
untuk (roshambo5 it: roshambo5.values ())
Table.put (IT, Enummap baru <roshambo5, hasil> (roshambo5.class));
initrow (kertas, gambar, kalah, menang);
initrow (gunting, menang, menarik, kalah);
initrow (rock, kalah, menang, menggambar);
}
static void initrow (roshambo5 IT, hasil vap, hasil vsissors, hasil vrock) {
Enummap <roshambo5, hasil> baris = roshambo5.table.get (it);
row.put (roshambo5.paper, vpaper);
row.put (roshambo5.scissors, vscissors);
row.put (roshambo5.rock, vrock);
}
Hasil publik bersaing (roshambo5 it) {
return table.get (this) .get (it);
}
public static void main(String[] args) {
Roshambo.Play (Roshambo5.class, 20);
}
}/ * Output yang sama seperti roshambo2.java * ///: ~
Kami juga dapat menggunakan fitur instance enumerasi dengan nilai tetap untuk menggunakan data untuk metode implementasi paling sederhana.
Copy kode kodenya sebagai berikut:
//: disebutkan/roshambo6.java
// enum menggunakan "tabel" alih -alih beberapa pengiriman.
paket disebutkan;
Impor Static Enumerated.Outcome.*;
enum roshambo6 mengimplementasikan pesaing <oshambo6> {
Kertas, gunting, batu;
Hasil statis pribadi [] [] tabel = {
{Draw, Lose, Win}, // Paper
{Win, Draw, Lose}, // Scissors
{Lose, Win, Draw}, // Rock
};
Hasil publik bersaing (roshambo6 lainnya) {
tabel pengembalian [this.ordinal ()] [Other.ordinal ()];
}
public static void main(String[] args) {
Roshambo.Play (Roshambo6.class, 20);
}
} ///: ~