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

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);
    }

}

发布了189 篇原创文章 · 获赞 58 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/Coder_py/article/details/103949425