美文网首页
Java编程思想---枚举类型

Java编程思想---枚举类型

作者: Cool_Pomelo | 来源:发表于2020-01-12 20:43 被阅读0次

    Java编程思想---枚举类型

    基本enum特性

    调用enum的values()方法,可以遍历enum实例,values方法返回enum实例数组,而且该数组中的元素严格保持在enum中声明时的顺序

    
    public enum Shrubbery {
    
        GROUND,
        CRAWLING,
        HANGING
    }
    
    public class EnumClass {
    
        public static void main(String[] args) {
    
            for (Shrubbery s : Shrubbery.values()) {
    
    //            ordinal方法返回一个int值  这是每个enum实例在声明时的次序 从 0 开始
                System.out.println(s + "orginal  " + s.ordinal());
    
                System.out.println("_________________");
    
    
    //            enum类实现了Comparable接口 所以具有compareTo方法
                System.out.println(s.compareTo(Shrubbery.CRAWLING ) + "");
    
                System.out.println("_________________");
    
    //            可以用 == 来比较enum实例  编译器会自动提供equal和hashcode方法
                System.out.println(s == Shrubbery.CRAWLING);
    
                System.out.println("_________________");
    
    
    //            getDeclaringClass方法告诉我们所属的enum类
                System.out.println(s.getDeclaringClass());
    
                System.out.println("_________________");
    
    //            name方法反复enum实例声明时的名字
                System.out.println(s.name());
    
            }
    
            for (String s:"jdddh hfhfj jfjkfjf".split(" ")) {
    
    //            valueOf根据给定的名字返回相对应的enum实例
                Shrubbery shrubbery = Enum.valueOf(Shrubbery.class,s);
    
                System.out.println(shrubbery);
            }
    
        }
    }
    
    
    

    向enum中添加新的方法

    可以向enum中添加方法,enum甚至可以有main()方法

    public enum OzWitch {
    
    //    枚举类实例能够返回对自身的描述,可以提供一个构造器,专门负责处理这个额外的信息
    //    然后添加一个方法,返回这个描述信息
    
    //    如果打算添加自己的方法,要在enum实例序列最后添加一个分号
    //    同时你要先定义enum实例,再定义任何方法或者属性
    
    
    
    
        // Instances must be defined first, before methods:
    
        WEST("Miss Gulch, aka the Wicked Witch of the West"),
    
        NORTH("Glinda, the Good Witch of the North"),
    
        EAST("Wicked Witch of the East, wearer of the Ruby " +
                "Slippers, crushed by Dorothy’s house"),
    
        SOUTH("Good by inference, but missing");
    
    
        private String description;
    
        // Constructor must be package or private access:
        private OzWitch(String description) {
            this.description = description;
        }
        public String getDescription() { return description; }
        public static void main(String[] args) {
            for(OzWitch witch : OzWitch.values())
                print(witch + ": " + witch.getDescription());
        }
    
    
    }
    
    

    覆盖enum方法

    public enum SpaceShip {
    
    
    //    覆盖toString方法
    
    //     以我们想要的方式来生成字符串描述信息
    
    
        SCOUT, CARGO, TRANSPORT, CRUISER, BATTLESHIP, MOTHERSHIP;
        public String toString() {
            String id = name();
            String lower = id.substring(1).toLowerCase();
            return id.charAt(0) + lower;
        }
        public static void main(String[] args) {
            for(SpaceShip s : values()) {
                System.out.println(s);
            }
        }
    
    
    }
    
    

    Switch中使用enum

    public enum Signal {
    
        GREEN, YELLOW, RED,
    
    }
    
    public class TrafficLight {
    
    //    switch中使用enum
    
        Signal color = Signal.RED;
    
    
        public void change() {
            switch(color) {
    // Note that you don’t have to say Signal.RED
    // in the case statement:
                case RED: color = Signal.GREEN;
                    break;
                case GREEN: color = Signal.YELLOW;
                    break;
                case YELLOW: color = Signal.RED;
                    break;
            }
        }
    
    
        public String toString() {
            return "The traffic light is " + color;
        }
    
    
        public static void main(String[] args) {
            TrafficLight t = new TrafficLight();
            for(int i = 0; i < 7; i++) {
                print(t);
                t.change();
            }
        }
    
    }
    
    
    
    

    Values( )方法

    public enum Explore {
    
        HERE, THERE
    
    
    }
    
    public class Reflection {
    
    //    values方法从何而来?
    
    //    利用反射机制查看一下
    
    
    
        public static Set<String> analyze(Class<?> enumClass) {
            print("----- Analyzing " + enumClass + " -----");
            print("Interfaces:");
            for(Type t : enumClass.getGenericInterfaces())
                print(t);
            print("Base: " + enumClass.getSuperclass());
            print("Methods: ");
            Set<String> methods = new TreeSet<String>();
            for(Method m : enumClass.getMethods())
                methods.add(m.getName());
            print(methods);
            return methods;
        }
        public static void main(String[] args) {
            Set<String> exploreMethods = analyze(Explore.class);
            Set<String> enumMethods = analyze(Enum.class);
            print("Explore.containsAll(Enum)? " +
                    exploreMethods.containsAll(enumMethods));
            printnb("Explore.removeAll(Enum): ");
            exploreMethods.removeAll(enumMethods);
            print(exploreMethods);
    // Decompile the code for the enum:
    //        OSExecute.command("javap Explore");
        }
    }
    
    

    实现,非继承

    enum可以实现一个或多个接口

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

    随机选取

    利用泛型

    
    public class Enums {
    
    
    //    随机选择
    
    //  <T extends Enum<T>>  表示T是一个enum实例
    
    //    Class<T>作为参数我们就可以利用Class对象得到enum实例的数组了
    
    
        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()方法示例:

    public 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) + " " + "\n");
    
        }
    }
    
    
    

    使用接口组织枚举

    在一个接口内部,创建实现该接口的枚举

    public interface Food {
    
    //    接口内部 创建实现该接口的枚举 以此将元素分组
    
    //    假设想用enum来表示不同的事物  同时还希望每个enum元素仍然保持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;
        }
    
    //    对于eunum,实现接口是使其子类化的唯一办法
    //    所以嵌入在food中的每个enum都实现了food接口
    
    public class TypeFod {
    
        public static void main(String[] args) {
    
            Food food = Food.Appetizer.SALAD;
    
            food = Food.MainCourse.LASAGNE;
    
            food = Food.Dessert.GELATO;
    
            food = Food.Coffee.CAPPUCCINO;
    
        }
    }
    
    }
    
    
    
    
    

    枚举中的枚举:

    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);
        }
    
    //    每一个Course的实例都将其对应的Class对象作为构造器的参数
    //    通过getEnumConstants可以获取某个Food子类的所有enum实例
    //
    
    }
    
    public class Meal {
    
    //    从每一个Course实例随机选择一个food 生成一份菜单
        public static void main(String[] args) {
    
            for (int i = 0; i < 5; i++) {
    
                for (Course course : Course.values()) {
    
                    Food food = course.randomSelection();
    
                    System.out.println(food);
    
                }
    
                System.out.println("-------------");
            }
    
        }
    }
    
    

    enum嵌套在一个enum:

    public enum SecurityCategory {
    
    
    //    更加高效简洁的管理枚举的方法
    
    //    将一个enum 嵌套在另一个enum里面
    
        STOCK(Security.Stock.class), BOND(Security.Bond.class);
    
        Security[] values;
    
    
        SecurityCategory(Class<? extends Security> kind) {
            values = kind.getEnumConstants();
        }
    
    
    //    Security接口是将其包含的enum组合成一个公共类型
        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 category =
                        Enums.random(SecurityCategory.class);
                System.out.println(category + ": " +
                        category.randomSelection());
            }
        }
    
    
    }
    
    

    使用EnumSet代替标志

    public enum AlarmPoints {
    
    //    enumset的元素必须来自于一个enum
    
    //    下面的enum表示在一座大楼中
    
    //    警报传感器的安放位置
    
        STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3,
        OFFICE4, BATHROOM, UTILITY, KITCHEN
    
    
    }
    
    
    
    
    public class EnumSets {
    
    //    用EnumSets来跟踪报警器的状态
    
    
        public static void main(String[] args) {
    
            EnumSet<AlarmPoints> points =
                    EnumSet.noneOf(AlarmPoints.class); // Empty set
    
    
            points.add(BATHROOM);
    
            print(points);
    
            points.addAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));
    
            print(points);
    
            points = EnumSet.allOf(AlarmPoints.class);
    
            points.removeAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));
    
            print(points);
    
            points.removeAll(EnumSet.range(OFFICE1, OFFICE4));
    
            print(points);
    
            points = EnumSet.complementOf(points);
    
            print(points);
    
        }
    }
    
    

    enum超过64个元素?:

    public class BigEnumSet {
    
    //    EnumSet的基础是long,一个long值有64位  而一个enum实例只需要一位 bit 表示其是否存在
    
    //    也就是 在不超过一个long的表达能力的情况下  EnumSets可以应用于最多不超过64个元素的enum
    
    //    所以如果元素超过了64个会发生啥?
    
        enum Big { 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<Big> bigEnumSet = EnumSet.allOf(Big.class);
            System.out.println(bigEnumSet);
        }
    }
    
    

    使用EnumMap

    命令设计模式:

    public interface Command {
    
        void action();
    
    }
    
    
    public class EnumMaps {
    
    //    EnumMap 是一种特殊的Map  它要求其中的键必须来自于一个enum
    
    
        public static void main(String[] args) {
    
            EnumMap<AlarmPoints,Command> em =
                    new EnumMap<AlarmPoints,Command>(AlarmPoints.class);
    
            em.put(KITCHEN, new Command() {
                public void action() { print("Kitchen fire!"); }
            });
    
            em.put(BATHROOM, new Command() {
                public void action() { print("Bathroom alert!"); }
            });
    
            for(Map.Entry<AlarmPoints,Command> e : em.entrySet()) {
                printnb(e.getKey() + ": ");
                e.getValue().action();
            }
    
    
            try { // If there’s no value for a particular key:
                em.get(UTILITY).action();
            } catch(Exception e) {
                print(e);
            }
    
    
        }
    }
    
    
    

    常量相关的方法

    
    public enum ConstantSpecificMethod {
    
    
    //    Java的enum有一个有趣的特性  允许你为enum实例编写方法  从而为每个enum实例赋予不同的行为
    
    //    要实现的话,你需要为enum定义一个或多个abstract方法 然后为每个enum实例实现该抽象方法
    
    
        DATE_TIME {
            String getInfo() {
                return
                        DateFormat.getDateInstance().format(new Date());
            }
        },
    
    
        CLASSPATH {
            String getInfo() {
                return System.getenv("CLASSPATH");
            }
        },
    
    
        VERSION {
            String getInfo() {
                return System.getProperty("java.version");
            }
        };
    
    
        abstract String getInfo();
    
    
        public static void main(String[] args) {
            for(ConstantSpecificMethod csm : values())
                System.out.println(csm.getInfo());
        }
    }
    
    
    

    但是我们并不能真的将enum实例作为一个类型去使用:

    
    public enum LikeClasses {
    
        WINKEN { void behavior() { print("Behavior1"); } },
    
        BLINKEN { void behavior() { print("Behavior2"); } },
    
        NOD { void behavior() { print("Behavior3"); } };
    
        abstract void behavior();
    
    }
    
    
    public class NotClasses {
    
    //    编译器不允许我们将一个enum实例当做class类型
    
    //    void f1(LikeClasses.WINKEN instance) {} // Nope
    }
    
    

    洗车的例子:

    
    public class CarWash {
    
    //    关于洗车的例子
    
    //    洗车的时候提供一个选择菜单  每个选择对应一个不同的动作
    
    //    可以将一个常量相关的方法关联到一个选择上
    
    //    再使用一个enumset来保存客户的选择
    
    
        public enum Cycle {
            UNDERBODY {
                void action() { print("Spraying the underbody"); }
            },
            WHEELWASH {
                void action() { print("Washing the wheels"); }
            },
            PREWASH {
                void action() { print("Loosening the dirt"); }
            },
            BASIC {
                void action() { print("The basic wash"); }
            },
            HOTWAX {
                void action() { print("Applying hot wax"); }
            },
            RINSE {
                void action() { print("Rinsing"); }
            },
            BLOWDRY {
                void action() { print("Blowing dry"); }
            };
            abstract void action();
        }
    
    
        EnumSet<Cycle> cycles =
                EnumSet.of(Cycle.BASIC, Cycle.RINSE);
    
        public void add(Cycle cycle) {
    
            cycles.add(cycle);
    
        }
    
        public void washCar() {
    
            for(Cycle c : cycles)
                c.action();
    
        }
    
        public String toString() {
    
            return cycles.toString();
    
        }
    
        public static void main(String[] args) {
            CarWash wash = new CarWash();
            print(wash);
            wash.washCar();
    // Order of addition is unimportant:
            wash.add(Cycle.BLOWDRY);
            wash.add(Cycle.BLOWDRY); // Duplicates ignored
            wash.add(Cycle.RINSE);
            wash.add(Cycle.HOTWAX);
            print(wash);
            wash.washCar();
        }
    }
    
    
    

    覆盖常量相关方法:

    
    public enum OverrideConstantSpecific {
    
    //    是否可以覆盖常量相关的方法呢? 当然可以
    
        NUT, BOLT,
    
        WASHER {
            void f() { print("Overridden method"); }
        };
    
        void f() { print("default behavior"); }
    
        public static void main(String[] args) {
            for(OverrideConstantSpecific ocs : values()) {
                printnb(ocs + ": ");
                ocs.f();
            }
        }
    
    
    }
    
    

    使用enum的责任链

    
    public class Mail {
    
    //    责任链设计模式
    
    //    程序员以不同的方式来解决一个问题  然后将它们链接到一起
    
    //    以一个邮局的模型为例,邮局需要以尽可能通用的方式来处理每一封邮件,并且要不断尝试处理邮件 直到该邮件被认定为一封死信
    
    //    邮件的每个关键特征都可以用enum来表示  程序将随机生成Mail对象
    
        // The NO’s lower the probability of random selection:
        enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,NO5}
    
        enum Scannability {UNSCANNABLE,YES1,YES2,YES3,YES4}
    
        enum Readability {ILLEGIBLE,YES1,YES2,YES3,YES4}
    
        enum Address {INCORRECT,OK1,OK2,OK3,OK4,OK5,OK6}
    
        enum ReturnAddress {MISSING,OK1,OK2,OK3,OK4,OK5}
    
        GeneralDelivery generalDelivery;
    
        Scannability scannability;
    
        Readability readability;
    
        Address address;
    
        ReturnAddress returnAddress;
    
        static long counter = 0;
    
        long id = counter++;
    
        public String toString() { return "Mail " + id; }
    
        public String details() {
            return toString() +
                    ", General Delivery: " + generalDelivery +
                    ", Address Scanability: " + scannability +
                    ", Address Readability: " + readability +
                    ", Address Address: " + address +
                    ", Return address: " + returnAddress;
        }
    
    
        // Generate test Mail:
    //    负责随机的创建用于测试的邮件
        public static Mail randomMail() {
            Mail m = new Mail();
            m.generalDelivery= Enums.random(GeneralDelivery.class);
            m.scannability = Enums.random(Scannability.class);
            m.readability = Enums.random(Readability.class);
            m.address = Enums.random(Address.class);
            m.returnAddress = Enums.random(ReturnAddress.class);
            return m;
        }
    
    
        public static Iterable<Mail> generator(final int count) {
            return new Iterable<Mail>() {
                int n = count;
                public Iterator<Mail> iterator() {
                    return new Iterator<Mail>() {
                        public boolean hasNext() { return n-- > 0; }
                        public Mail next() { return randomMail(); }
                        public void remove() { // Not implemented
                            throw new UnsupportedOperationException();
                        }
                    };
                }
            };
        }
    
    
    }
    
    
    
    
    public class PostOffice {
    
        enum MailHandler {
            GENERAL_DELIVERY {
                boolean handle(Mail m) {
                    switch(m.generalDelivery) {
                        case YES:
                            print("Using general delivery for " + m);
                            return true;
                        default: return false;
                    }
                }
            },
            MACHINE_SCAN {
                boolean handle(Mail m) {
                    switch(m.scannability) {
                        case UNSCANNABLE: return false;
                        default:
                            switch(m.address) {
                                case INCORRECT: return false;
                                default:
                                    print("Delivering "+ m + " automatically");
                                    return true;
                            }
                    }
                }
            },
            VISUAL_INSPECTION {
                boolean handle(Mail m) {
                    switch(m.readability) {
                        case ILLEGIBLE: return false;
                        default:
                            switch(m.address) {
                                case INCORRECT: return false;
                                default:
                                    print("Delivering " + m + " normally");
                                    return true;
                            }
                    }
                }
            },
            RETURN_TO_SENDER {
                boolean handle(Mail m) {
                    switch(m.returnAddress) {
                        case MISSING: return false;
                        default:
                            print("Returning " + m + " to sender");
                            return true;
                    }
                }
            };
            abstract boolean handle(Mail m);
        }
        static void handle(Mail m) {
            for(MailHandler handler : MailHandler.values())
                if(handler.handle(m))
                    return;
            print(m + " is a dead letter");
        }
    
    
        public static void main(String[] args) {
            for(Mail mail : Mail.generator(10)) {
                print(mail.details());
                handle(mail);
                print("*****");
            }
        }
    }
    
    

    使用enum的状态机

    public enum Input {
    
        NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100),
    
        TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50),
    
        ABORT_TRANSACTION {
            public int amount() { // Disallow
                throw new RuntimeException("ABORT.amount()");
            }
        },
    
    
        STOP { // This must be the last instance.
            public int amount() { // Disallow
                throw new RuntimeException("SHUT_DOWN.amount()");
            }
        };
    
    
        int value; // In cents
    
        Input(int value) { this.value = value; }
    
    
        Input() {}
    
        int amount() { return value; }; // In cents
    
        static Random rand = new Random(47);
    
        public static Input randomSelection() {
    // Don’t include STOP:
            return values()[rand.nextInt(values().length - 1)];
        }
    
    
    }
    
    public enum Category {
    
        MONEY(NICKEL, DIME, QUARTER, DOLLAR),
        ITEM_SELECTION(TOOTHPASTE, CHIPS, SODA, SOAP),
        QUIT_TRANSACTION(ABORT_TRANSACTION),
        SHUT_DOWN(STOP);
    
    
        private Input[] values;
    
        Category(Input... types) { values = types; }
    
        private static EnumMap<Input,Category> categories =
                new EnumMap<Input,Category>(Input.class);
    
        static {
            for(Category c : Category.class.getEnumConstants())
                for(Input type : c.values)
                    categories.put(type, c);
        }
    
        public static Category categorize(Input input) {
            return categories.get(input);
        }
    }
    
    public class VendingMachine {
    
        private static State state = State.RESTING;
        private static int amount = 0;
        private static Input selection = null;
        enum StateDuration { TRANSIENT } // Tagging enum
        enum State {
            RESTING {
                void next(Input input) {
                    switch(Category.categorize(input)) {
                        case MONEY:
                            amount += input.amount();
                            state = ADDING_MONEY;
                            break;
                        case SHUT_DOWN:
                            state = TERMINAL;
                        default:
                    }
                }
            },
            ADDING_MONEY {
                void next(Input input) {
                    switch(Category.categorize(input)) {
                        case MONEY:
                            amount += input.amount();
                            break;
                        case ITEM_SELECTION:
                            selection = input;
                            if(amount < selection.amount())
                                print("Insufficient money for " + selection);
                            else state = DISPENSING;
                            break;
                        case QUIT_TRANSACTION:
                            state = GIVING_CHANGE;
                            break;
                        case SHUT_DOWN:
                            state = TERMINAL;
                        default:
                    }
                }
            },
            DISPENSING(StateDuration.TRANSIENT) {
                void next() {
                    print("here is your " + selection);
                    amount -= selection.amount();
                    state = GIVING_CHANGE;
                }
            },
            GIVING_CHANGE(StateDuration.TRANSIENT) {
                void next() {
                    if(amount > 0) {print("Your change: " + amount);
                        amount = 0;
                    }
                    state = RESTING;
                }
            },
            TERMINAL { void output() { print("Halted"); } };
            private boolean isTransient = false;
            State() {}
            State(StateDuration trans) { isTransient = true; }
            void next(Input input) {
                throw new RuntimeException("Only call " +
                        "next(Input input) for non-transient states");
            }
            void next() {
                throw new RuntimeException("Only call next() for " +
                        "StateDuration.TRANSIENT states");
            }
            void output() { print(amount); }
        }
        static void run(Generator<Input> gen) {
            while(state != State.TERMINAL) {
                state.next(gen.next());
                while(state.isTransient)
                    state.next();
                state.output();
            }
        }
        public static void main(String[] args) {
            Generator<Input> gen = new RandomInputGenerator();
            if(args.length == 1)
                gen = new FileInputGenerator(args[0]);
            run(gen);
        }
    }
    
    
    

    多路分发

    “剪刀石头布游戏”

    public enum Outcome {
    
    //    结果
    
        WIN,
    
        LOSE,
    
        DRAW
    }
    public class Paper implements Item{
    
    //    对应剪刀石头布 中的 布
        @Override
        public Outcome compete(Item item) {
            return item.eval(this);
        }
    
    //    一样肯定平局
        @Override
        public Outcome eval(Paper paper) {
            return Outcome.DRAW;
        }
    
    
    //
        @Override
        public Outcome eval(Scissors scissors) {
            return Outcome.WIN;
        }
    
        @Override
        public Outcome eval(Rock rock) {
            return Outcome.LOSE;
        }
    
        @Override
        public String toString() {
            return "Paper{}";
        }
    }
    
    
    
    public class Rock implements Item{
    
        //    对应剪刀石头布 中的 石头
    
        @Override
        public Outcome compete(Item item) {
            return item.eval(this);
        }
    
        @Override
        public Outcome eval(Paper paper) {
            return Outcome.WIN;
        }
    
        @Override
        public Outcome eval(Scissors scissors) {
            return Outcome.LOSE;
        }
    
        @Override
        public Outcome eval(Rock rock) {
            return Outcome.DRAW;
        }
    
        @Override
        public String toString() {
            return "Rock{}";
        }
    }
    
    
    public class Scissors implements Item{
    
    //    //    对应剪刀石头布 中的 剪刀
        @Override
        public Outcome compete(Item item) {
            return item.eval(this);
        }
    
        @Override
        public Outcome eval(Paper paper) {
            return Outcome.LOSE;
        }
    
        @Override
        public Outcome eval(Scissors scissors) {
            return Outcome.DRAW;
        }
    
        @Override
        public Outcome eval(Rock rock) {
            return Outcome.WIN;
        }
    
        @Override
        public String toString() {
            return "Scissors{}";
        }
    }
    
    public interface Item {
    
        Outcome compete(Item item);
    
        Outcome eval(Paper paper);
    
        Outcome eval(Scissors scissors);
    
        Outcome eval(Rock rock);
    }
    
    
    public class RoShamBo1 {
    
    
        static final int SIZE = 20;
    
        private static Random random = new Random(47);
    
    //    随机出 剪刀石头布
        public static Item newItem(){
            switch (random.nextInt(3)){
    
                default:
    
                case 0: return new Scissors();
    
                case 1: return new Paper();
    
                case 2: return new Rock();
            }
    
        }
    
    
        public static  void match(Item a,Item b){
    
            System.out.println(
                    a + "vs  " + b + ":  " + a.compete(b)
            );
        }
        public static void main(String[] args) {
    
    //        随机比赛 20次
            for (int i = 0; i < SIZE; i++) {
    
                match(newItem(),newItem());
            }
        }
    }
    

    使用enum分发

    
    public enum RoShamBo2 implements Competitor<RoShamBo2>{
    
    
    //    使用enum分发
    
    
        PAPER(DRAW, LOSE, WIN),
        SCISSORS(WIN, DRAW, LOSE),
        ROCK(LOSE, WIN, DRAW);
        private Outcome vPAPER, vSCISSORS, vROCK;
        RoShamBo2(Outcome paper,Outcome scissors,Outcome rock) {
            this.vPAPER = paper;
            this.vSCISSORS = scissors;
            this.vROCK = rock;
        }
        public Outcome compete(RoShamBo2 it) {
            switch(it) {
                default:
                case PAPER: return vPAPER;
                case SCISSORS: return vSCISSORS;
                case ROCK: return vROCK;
            }
        }
        public static void main(String[] args) {
            RoShamBo.play(RoShamBo2.class, 20);
        }
    
    
    }
    
    
    

    使用常量相关的方法

    
    public enum RoShamBo3 implements Competitor<RoShamBo3> {
    
    //    使用常量相关的方法
    
        PAPER {
            public Outcome compete(RoShamBo3 it) {
                switch(it) {
                    default: // To placate the compiler
                    case PAPER: return DRAW;
                    case SCISSORS: return LOSE;
                    case ROCK: return WIN;
                }
            }
        },
        SCISSORS {
            public Outcome compete(RoShamBo3 it) {
                switch(it) {
                    default:
                    case PAPER: return WIN;
                    case SCISSORS: return DRAW;
                    case ROCK: return LOSE;
                }
            }
        },
        ROCK {
            public Outcome compete(RoShamBo3 it) {
                switch(it) {
                    default:
                    case PAPER: return LOSE;
                    case SCISSORS: return WIN;
                    case ROCK: return DRAW;
                }
            }
        };
        public abstract Outcome compete(RoShamBo3 it);
        public static void main(String[] args) {
            RoShamBo.play(RoShamBo3.class, 20);
        }
    }
    
    
    

    简化:

    public enum RoShamBo4 implements Competitor<RoShamBo4> {
        ROCK {
            public Outcome compete(RoShamBo4 opponent) {
                return compete(SCISSORS, opponent);
            }
        },
        SCISSORS {
            public Outcome compete(RoShamBo4 opponent) {
                return compete(PAPER, opponent);
            }
        },
        PAPER {
            public Outcome compete(RoShamBo4 opponent) {
                return compete(ROCK, opponent);
            }
        };
        Outcome compete(RoShamBo4 loser, RoShamBo4 opponent) {
            return ((opponent == this) ? Outcome.DRAW
                    : ((opponent == loser) ? Outcome.WIN
                    : Outcome.LOSE));
        }
        public static void main(String[] args) {
            RoShamBo.play(RoShamBo4.class, 20);
        }
    }
    
    
    

    使用EnumMap分发

    public enum RoShamBo5 implements Competitor<RoShamBo5> {
    
    //      使用EnumMap分发
    
    
            PAPER, SCISSORS, ROCK;
    
    
            static EnumMap<RoShamBo5, EnumMap<RoShamBo5, Outcome>>
            table = new EnumMap<RoShamBo5,
            EnumMap<RoShamBo5,Outcome>>(RoShamBo5.class);
    
    
            static {
                    for(RoShamBo5 it : RoShamBo5.values())
                    table.put(it, new EnumMap<RoShamBo5,Outcome>(RoShamBo5.class));
                    initRow(PAPER, DRAW, LOSE, WIN);
                    initRow(SCISSORS, WIN, DRAW, LOSE);
                    initRow(ROCK, LOSE, WIN, DRAW);
            }
    
    
            static void initRow(RoShamBo5 it,
                            Outcome vPAPER, Outcome vSCISSORS, Outcome vROCK) {
                    EnumMap<RoShamBo5,Outcome> row =
                            RoShamBo5.table.get(it);
                    row.put(RoShamBo5.PAPER, vPAPER);
                    row.put(RoShamBo5.SCISSORS, vSCISSORS);
                    row.put(RoShamBo5.ROCK, vROCK);
            }
    
    
            public Outcome compete(RoShamBo5 it) {
                return table.get(this).get(it);
            }
    
    
            public static void main(String[] args) {
                RoShamBo.play(RoShamBo5.class, 20);
            }
    }
    
    
    
    

    使用二维数组

    public enum RoShamBo6 implements Competitor<RoShamBo6> {
    
    //    用数组实现分发
    
    
        PAPER, SCISSORS, ROCK;
    
        private static Outcome[][] table = {
                { DRAW, LOSE, WIN }, // PAPER
                { WIN, DRAW, LOSE }, // SCISSORS
                { LOSE, WIN, DRAW }, // ROCK
        };
    
    
        public Outcome compete(RoShamBo6 other) {
            return table[this.ordinal()][other.ordinal()];
        }
    
    
        public static void main(String[] args) {
            RoShamBo.play(RoShamBo6.class, 20);
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:Java编程思想---枚举类型

          本文链接:https://www.haomeiwen.com/subject/mpewactx.html