public class EnumClass {
public static void main(String[] args) {
Arrays.asList(Shrubbery.values()).forEach(e->{
System.out.println(e + "ordinal:" + e.ordinal());
System.out.println(e.equals(Shrubbery.CRAWLING) + " ");
System.out.println(e == Shrubbery.CRAWLING);
System.out.println(e.name());
});
Arrays.asList("HANGING CRAWLING GROUND".split(" ")).forEach(s->{
Shrubbery shrub = Enum.valueOf(Shrubbery.class,s);
System.out.println(shrub);
});
}
}
可以看出,枚举是单例模式,可以使用 == 或者equals来进行比较,而valueOf 可以使用枚举类型和名称创建出一个真是的枚举;
下面是一从随机抽取枚举类型的类:
/**
* 从class中随机抽取枚举
*/
public class Enums {
private static Random random = new Random(48);
public static <T extends Enum<T>> T random(Class<T> type){
return random(type.getEnumConstants());
}
public static <T> T random(T[] ts){
return ts[random.nextInt(ts.length)];
}
}
下面的接口中有许多枚举:
public interface Food {
enum Appetizer implements Food {
SALAD,SOUP,SPRING_ROLLS;
}
enum Maincourse implements Food {
LASAGNE,BURRITO,PAD_THAI,LENTILS,HUMMOUS,VINDALOO;
}
enum Dessert implements Food {
TIRAMISU,GELATO,BLACK_FOREST_CAKE,FRUIT,CREME_CARAMEL;
}
enum Coffee implements Food {
BLACK_COFFEE,DECAF_COFFEE,ESPRESSO,LATTE,CAPPUCCINO,TEA,HERB_TEA;
}
}
对于枚举而言,实现接口是使其唯一子例化的行为,但是这些枚举要是使用起来,可就不那么方便了,可以提供一种管理方法:
public enum Course {
APPETIZER(Food.Appetizer.class),
MAINCOURSE(Food.Maincourse.class),
DESSERT(Food.Dessert.class),
COFFEE(Food.Coffee.class);
private Food[] values;
private Course(Class<? extends Food> kind){
values = kind.getEnumConstants();
}
public Food randomSelection(){
return Enums.random(values);
}
public static void main(String[] args) {
IntStream.range(0,5).forEach(i->{
Arrays.asList(values()).forEach(c->{
Food f = c.randomSelection();
System.out.println(f);
});
System.out.println("-------");
});
}
}
SPRING_ROLLS
PAD_THAI
GELATO
DECAF_COFFEE
-------
SALAD
BURRITO
BLACK_FOREST_CAKE
ESPRESSO
-------
SOUP
LASAGNE
FRUIT
HERB_TEA
-------
SPRING_ROLLS
HUMMOUS
BLACK_FOREST_CAKE
ESPRESSO
-------
SPRING_ROLLS
LASAGNE
GELATO
TEA
-------
在上面的类中,有意识的将无参构造函数私有化,但是这并不影响这个枚举的使用,因为我们只能在enum定义的内部使用其构造器创建枚举实例,一旦枚举定义结束,编译器就不允许我们在使用其构造器来创建任何实例。
还有一种更加简洁的管理方式:
public enum Meal {
APPETIZER(Food.Appetizer.class),
MAINCOURSE(Food.Maincourse.class),
DESSERT(Food.Dessert.class),
COFFEE(Food.Coffee.class);
private Food[] values;
private Meal(Class<? extends Food> kind){
values = kind.getEnumConstants();
}
public interface Food {
enum Appetizer implements Food {
SALAD,SOUP,SPRING_ROLLS;
}
enum Maincourse implements Food {
LASAGNE,BURRITO,PAD_THAI,LENTILS,HUMMOUS,VINDALOO;
}
enum Dessert implements Food {
TIRAMISU,GELATO,BLACK_FOREST_CAKE,FRUIT,CREME_CARAMEL;
}
enum Coffee implements Food {
BLACK_COFFEE,DECAF_COFFEE,ESPRESSO,LATTE,CAPPUCCINO,TEA,HERB_TEA;
}
}
public Food randomSelection(){
return Enums.random(values);
}
public static void main(String[] args) {
IntStream.range(0,5).forEach(i->{
Arrays.asList(values()).forEach(c->{
Food f = c.randomSelection();
System.out.println(f);
});
System.out.println("-------");
});
}
}
这仅仅只是重新组织了一下代码,但这种方式使你的代码具有更加清晰的结构。