枚举

public enum Spiciness {
    NOT,MILD,MEDIUM,HOT,FLAMING
}

这里创建了一个Spiciness的枚举类型,它有5个具名值。枚举类型的实例是常量,用大写字母表示。

 

public class SimpleEnumUse {
    public static void main(String[] args) {
        Spiciness spiciness=Spiciness.HOT;
        System.out.println(spiciness); 

        for(Spiciness s:Spiciness.values()){
            System.out.println(s+" ordinal "+s.ordinal());
        }
    }
}

ordinal()方法表示某个特定的enum常量的声明顺序(从0开始);

values()方法按照常量的声明顺序,生成由这些常量值构成的数组。

name()方法返回enum实例声明时的名字,这与使用toString()效果相同。

valueOf()是在Enum中定义的static方法,根据给定的名字返回相应的enum实例。

 

public class Burrito {
    Spiciness degree;
    public Burrito(Spiciness degree){
        this.degree=degree;
    }
    public void describe(){
        System.out.println("This burrito is : ");
        switch (degree){
            case NOT:
                System.out.println("NOT");
                break;
            case MILD:
                System.out.println("MILD");
                break;
            case MEDIUM:
                System.out.println("MEDIUM");
                break;
            case HOT:
                System.out.println("HOT");
                break;
            case FLAMING:
                System.out.println("FLAMING");
                break;
        }
    }
    public static void main(String[] args) {
        Burrito
                burrito=new Burrito(Spiciness.HOT),
                burrito1=new Burrito(Spiciness.MILD),
                burrito2=new Burrito(Spiciness.FLAMING);
        burrito.describe();
        burrito1.describe();
        burrito2.describe();
    }
}

由于switch是要在有限的集合中进行选择,所以与enum正式绝佳的组合。

 

public class OzWitchTest {
    public static void main(String[] args) {
        for (OzWitch o:OzWitch.values()){
            System.out.println(o+" : "+o.getDescription());
        }
    }
}

每个枚举实例返回对自身的描述。提供一个构造器,专门负责这个额外的信息,然后提供一个方法,返回这个描述信息。

定义自己的方法,必须在enum实例序列的最后添加一个分号,同时必须先定义enum实例。

enum中的构造器和方法与普通的类没有区别。

 

public enum  SpaceShip {
    AA,BB,CC,DD,EE;

    @Override
    public String toString() {
        String name = name();
        String s = name.substring(1).toLowerCase();
        return name.charAt(0)+s;
    }

    public static void main(String[] args) {
        for(SpaceShip spaceShip:SpaceShip.values()){
            System.out.println(spaceShip);
        }
    }
}

覆盖enum的toString()方法。通过调用name()方法取得SpaceShip的名字,然后修改为只有首字母大写的格式。

 

public class TrafficLight {
    enum Signal{
        RED,GREEN,YELLOW
    }
    Signal color=Signal.RED;
    public void change(){
        switch (color){
            case RED:
                color=Signal.GREEN;
                break;
            case GREEN:
                color=Signal.YELLOW;
                break;
            case YELLOW:
                color=Signal.RED;
                break;
        }
    }

    @Override
    public String toString() {
        return "The trafficLight is "+color;
    }

    public static void main(String[] args) {
        TrafficLight t=new TrafficLight();
        for(int i=0;i<7;i++){
            System.out.println(t);
            t.change();
        }
    }
}

这里构造了一个小型状态机。

 

enum Search{HITHER,YON}

public class UpcastEnum {
    public static void main(String[] args) {
        Search[] vals=Search.values();
        Enum e=Search.HITHER; //Upcast
        //e.values(); Enum没有values()方法
        for(Enum en:e.getClass().getEnumConstants()){
            System.out.println(en);
        }
    }
}

values()方法是由编译器添加的static方法。如果将enum实例向上转型为Enum,那么values()方法则不可访问。

Class中的getEnumConstants()方法可以获取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)];
    }
}
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)+" ");
        }
    }
}

从枚举实例中进行随机选取。

Enums中将Class<T>作为参数,利用Class对象获得enum实例的数组,然后用重载后的random()方法,从数组中随机选取一个元素。

 

public enum SecurityCategory {
    STOCK(Security.Stock.class),
    BOND(Security.Bond.class);

    Security[] values;
    SecurityCategory(Class<? extends Security> 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 category=Enums.random(SecurityCategory.class); //随机选取实例
            System.out.println(category+" : "+category.randomSelection());
        }
    }
}

枚举中嵌套枚举。对于枚举而言,实现接口是使其子类化的唯一方法。

 

enum AlarmPoints{
    STAIR1,STAIR2,LOBBY,OFFICE1,OFFICE2,OFFICE3,OFFICE4,BATHROOM,UTILITY,KITCHEN
}

EnumSet适用于枚举的集合,其中的元素必须来自一个enum。

 

interface Command{
    void action();
}

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

EnumMap其中的key必须来自一个enum。没有为key调用put()方法来存入值得话,其对应值就是null。

 

public enum ConstantSpecificMethod {
    DATE_TIME{
        @Override
        String getInfo(){
            return DateFormat.getDateInstance().format(new Date());
        }
    },
    CLASSPATH{
        @Override
        String getInfo() {
            return System.getenv("CLASSPATH");
        }
    },
    VERSION{
        @Override
        String getInfo() {
            return System.getProperty("java.version");
        }
    };

    abstract String getInfo();

    public static void main(String[] args) {
        for(ConstantSpecificMethod csm:ConstantSpecificMethod.values()){
            System.out.println(csm.getInfo());
        }
    }
}

为enum实例编写方法,为每个enum实例赋予各自不同的行为。

 

这里编写一个石头剪刀布游戏。

enum Outcome {
    WIN,LOSE,DRAW
}

public interface Item {
    Outcome compete(Item item);
    Outcome eval(Paper paper);
    Outcome eval(Scissors scissors);
    Outcome eval(Rock rock);
}

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 "布";
    }
}

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 "剪刀";
    }
}

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 "石头";
    }
}
public class RoShamBo1 {
    static final int SIZE=10;
    private static Random random=new Random(66);
    public static Item newItem(){
        switch (random.nextInt(3)){
            default:
            case 0:
                return new Paper();
            case 1:
                return new Scissors();
            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) {
        for(int i=0;i<SIZE;i++){
            match(newItem(),newItem());
        }
    }
}

 

public interface Competitor<T extends Competitor<T>> {
    Outcome compete(T competitor);
}
public class RoShamBo {
    public static <T extends Competitor<T>> void match(T a,T b){
        System.out.println(a+" vs "+b+" : "+a.compete(b));
    }
    public static <T extends Enum<T> & Competitor<T>> void play(Class<T> rsbClass,int size){
        for(int i=0;i<size;i++){
            match(Enums.random(rsbClass),Enums.random(rsbClass));//随机选取两个实例
        }
    }
}
public enum RoShamBo2 implements Competitor<RoShamBo2> {
    PAPER(DRAW,LOSE,WIN), //顺序很重要
    SCISSORS(WIN,DRAW,LOSE), //与构造器的形参对应
    ROCK(LOSE,WIN,DRAW);

    private Outcome vPAPER,vSCISSORS,vROCK;
    RoShamBo2(Outcome paper,Outcome scissors,Outcome rock){
        vPAPER=paper;
        vSCISSORS=scissors;
        vROCK=rock;
    }

    @Override
    public Outcome compete(RoShamBo2 competitor) {
        switch (competitor){
            default:
            case PAPER:return vPAPER;
            case ROCK:return vROCK;
            case SCISSORS:return vSCISSORS;
        }
    }

    public static void main(String[] args) {
        RoShamBo.play(RoShamBo2.class,10);
    }
}

 

利用构造器初始化每个enum实例,并以“一组”结果作为参数。

比如PAPER vs SCISSORS,match()方法中a是PAPER ,b是SCISSORS,由于重写了compete()方法,返回vSCISSORS。构造器初始化了每个enum实例,PAPER中vSCISSORS是第二位,也就是LOSE。

 

public enum RoShamBo5 implements Competitor<RoShamBo5> {
    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,Outcome.DRAW,Outcome.LOSE,Outcome.WIN);
        initRow(SCISSORS,Outcome.WIN,Outcome.DRAW,Outcome.LOSE);
        initRow(ROCK,Outcome.LOSE,Outcome.WIN,Outcome.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);
    }
    @Override
    public Outcome compete(RoShamBo5 it) {
        return table.get(this).get(it);
    }

    public static void main(String[] args) {
        RoShamBo.play(RoShamBo5.class,10);
    }
}

 

import static enum_test.Outcome.*;
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
    };
    @Override
    public Outcome compete(RoShamBo6 competitor) {
        return table[this.ordinal()][competitor.ordinal()];
    }

    public static void main(String[] args) {
        RoShamBo.play(RoShamBo6.class,10);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值