Java基础系列(二十一)(枚举进阶)

switch语句中的enum
一般来说,在switch语句中只能使用整数值或者字符串,但是枚举实例天生就具备了整数值的次序,并且可以通过ordinal()方法来取得这个次序,所以我们可以在switch语句中使用enum。下面是在switch中使用enum的一个实例:

public class EnumTest {Size size = Size.SMALL; public static void main(String[] args) { EnumTest enumTest = new EnumTest(); for (int i = 0; i < 7; i++) { System.out.println(enumTest); enumTest.changeSize(); }}public void changeSize() { switch (size) { case SMALL: size = Size.MEDIUM; break; case MEDIUM: size = Size.LARGE; break; case LARGE: size = Size.EXTRA_LARGE; break; case EXTRA_LARGE: size = Size.SMALL; break; } }@Override public String toString() { return "The size is " + size; }}enum Size {SMALL,MEDIUM,LARGE,EXTRA_LARGE }

打印输出结果为:
The size is SMALL The size is MEDIUM The size is LARGE The size is EXTRA_LARGE The size is SMALL The size is MEDIUM The size is LARGE

可以看到在switch语句中使用enum是非常方便而且直观的,而且也增加了代码的可读性。
使用接口组织枚举
有时我们希望可以对一个enum中的元素进行分组,但是我们却无法继承这个enum,这就造成了一些困扰。后来,我们想到了在一个接口的内部,创建实现这个接口的枚举,以此可以将元素进行分组,可以达到将枚举元素分类组织的目的,下面我们来看代码:
//这段代码源自编程思想一书 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 class TypeOfFood {public static void main(String[] args) { Food food = Food.Appetizer.SALAD; food = Food.Coffee.BLACK_COFFEE; food = Food.Dessert.BLACK_FOREST_CAKE; food = Food.MainCourse.PAD_THAI; } }

这样使用显得有些臃肿,我们可以创建一个新的enum,然后用其实例包装Food中的每一个类:
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 kind) { values = kind.getEnumConstants(); }public Food randomSeletion() { return Enums.random(values); } }

然后编写一个方法用于随机选取一个枚举实例:
public class Enums {private static Random rand = new Random(47); public static > T random(Class ec) { return random(ec.getEnumConstants()); }public static T random(T[] values) { return values[rand.nextInt(values.length)]; } }

利用这些,我们可以模拟一个菜单的打印:
public class Meal {public static void main(String[] args) { for (int i = 0; i < 2; i++) { for (Course course : Course.values()) { Food food = course.randomSeletion(); System.out.println(food); } System.out.println("----"); } } }

打印结果如下:
SPRING_ROLLS VINDALOO FRUIT DECAF_COFFEE ---- SOUP VINDALOO FRUIT TEA ----

枚举嵌套
除了使用接口来组织枚举之外,我们还可以使用枚举的嵌套,就是将一个enum放到另一个enum中,具体使用方法如下:
public enum SecurityCategory {STOCK(Security.Stock.class), BOND(Security.Bond.class); Security[] values; SecurityCategory(Class kind) { values = kind.getEnumConstants(); }interface Security { enum Stock implements Security { SHORT, LONG, MARGIN } enum Bond implements Security { MUNICIPAL, JUNK } }public Security randomSelection() { return Enums.random(values); }public static void main(String[] args) { for (int i = 0; i < 10; i++) { SecurityCategory securityCategory = Enums.random(SecurityCategory.class); System.out.println(securityCategory + ": " + securityCategory.randomSelection()); } } }

打印结果:
BOND: MUNICIPAL BOND: MUNICIPAL STOCK: MARGIN STOCK: MARGIN BOND: JUNK STOCK: SHORT STOCK: LONG STOCK: LONG BOND: MUNICIPAL BOND: JUNK

Security接口的作用是将其包含的enum组合成一个公共类型,这一点是非常必要的。然后,SecurityCategory才能将Security中的enum作为其构造器的参数使用,以起到组织的效果。
【Java基础系列(二十一)(枚举进阶)】原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知
公众号
Java基础系列(二十一)(枚举进阶)
文章图片

    推荐阅读