《onjava进阶卷》01枚举类型5-9

48 阅读2分钟

5、实现,而不是继承

enum对象都继承自java.lang.Enum。Java不支持多重继承。可以创建实现了一个或多个接口的枚举类型

enum CartoonCharacter implements Supplier<CartoonCharacter> {  
    SLAPPY, SPANKY, PUNCHY, SILLY, BOUNCY, NUTTY, BOB;  
  
    private Random rand = new Random(47);  
  
    @Override  
    public CartoonCharacter get() {  
        return values()[rand.nextInt(values().length)];  
    }  
}  
  
public class EnumImplementation {  
    public static <T> void printNext(Supplier<T> rg) {  
        System.out.print(rg.get() + ", ");  
    }  
  
    public static void main(String[] args) {  
        CartoonCharacter cc = CartoonCharacter.BOB;  
        for (int i = 0; i < 10; i++) {  
            printNext(cc);  
        }  
    }  
}

6、随机选择

写一个从enum中随机选择实例的公共方法

public class Enums {  
    private static Random rand = new Random(47);  
  
    public static <T extends Enum<T>> T random(Class<T> ec) {  
        return random(ec.getEnumConstants());  
    }  
  
    public static <T> T random(T[] values) {  
        return values[rand.nextInt(values.length)];  
    }  
}

对random方法写个测试

enum Activity {  
    SITTING, LYING, STANDING, HOPPING, RUNNING, DODGING, JUMPING, FALLING, FLYING  
}  
  
public class RandomTest {  
    public static void main(String[] args) {  
        for (int i = 0; i < 20; i ++) {  
            System.out.print(Enums.random(Activity.class) + " ");  
        }  
    }  
}

7、使用接口来组织枚举

定义一个接口,在接口内定义枚举,枚举实现接口,可以通过这种方式实现元素的分类。

public interface Food {  
    enum Appetizer implements Food {  
        SALAD, SOUP, SPRING_ROLLS;  
    }  
  
    enum MainCourse implements Food {  
        LASAGNE, BURRITO, PAD_THAI, LENTILS, HUMMUS, 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;  
    }  
}

8、用EnumSet来代替标识

EnumSet同Set不允许重复元素存在且可以添加或删除元素。其内部实现是一个被用作位数组long型变量,所以它非常高效。

public enum AlarmPoints {  
    STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, BATHROOM, UTILITY, KITCHEN  
}
public class EnumSets {  
    public static void main(String[] args) {  
        EnumSet<AlarmPoints> points = EnumSet.noneOf(AlarmPoints.class);  
        points.add(BATHROOM);  
        System.out.println(points);  
        points.addAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));  
        System.out.println(points);  
        points = EnumSet.allOf(AlarmPoints.class);  
        points.removeAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));  
        System.out.println(points);  
        points.removeAll(EnumSet.range(OFFICE1, OFFICE4));  
        System.out.println(points);  
        points = EnumSet.complementOf(points);  
        System.out.println(points);  
    }  
}

9、使用EnumMap

EnumMap是一种特殊的Map,它要求自身所有的键来自某个枚举类型。

  
interface Command {  
    void action();  
}  
  
public class EnumMaps {  
    public static void main(String[] args) {  
        EnumMap<AlarmPoints, Command> em = new EnumMap<>(AlarmPoints.class);  
        em.put(KITCHEN, () -> System.out.println("Kitchen file!"));  
        em.put(BATHROOM, () -> System.out.println("Bathroom alert!"));  
        for (Map.Entry<AlarmPoints, Command> e : em.entrySet()) {  
            System.out.println(e.getKey() + ": ");  
            e.getValue().action();  
        }  
        try {  
            em.get(UTILITY).action();  
        } catch (Exception e) {  
            System.out.println("Excepted: " + e);  
        }  
    }  
}