2015年7月3日 星期五

Enum、EnumMap、EnumSet

在1.5之前是這樣子寫的,一個棋類,有三種棋
class Chess {
    public static final int ELEPHANT = 0; // 象棋
    public static final int JUMP = 1; // 跳棋
    public static final int LOOP = 2; // 圍棋

    private int type;

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

用類.屬性當然OK,但顯示出來是數字,不夠直覺; 但因為是傳int,所以傳負的也不會報錯
public class TestEnum {
    public static void main(String[] args) {
        Chess chess = new Chess();
        chess.setType(Chess.ELEPHANT);
        System.out.println(chess.getType());
        chess.setType(-5);
        System.out.println(chess.getType());
    }
}

1.5有了Enum,在java.lang,是個class,用法如下
public enum Chess {
    ELEPHANT, JUMP, LOOP;
}

class ChessType {
    private Chess type;

    public Chess getType() {
        return type;
    }

    public void setType(Chess type) {
        this.type = type;
    }
}

測試類
public class TestEnum {
    public static void main(String[] args) {
        System.out.println(Chess.ELEPHANT);
        ChessType chess = new ChessType();
        chess.setType(Chess.JUMP);// 只能傳Enum
        System.out.println(chess.getType());

        for (Chess chess : Chess.values()) {//取得全部
            System.out.println(chess);//等同chess.name()
            System.out.println(chess.ordinal() + "=" + chess.name());
        }
        
        for (Chess chess : Chess.values()) {
            switchMethod(chess);
        }
    }

    private static void switchMethod(Chess chess) {//中文轉換
        switch (chess) {
            case ELEPHANT: {
                System.out.println("象棋");
                break;
            }
            case JUMP: {
                System.out.println("跳棋");
                break;
            }
            case LOOP: {
                System.out.println("圍棋");
                break;
            }
            default: {
                System.out.println("無法騎");
            }
        }
    }
}

結果:
ELEPHANT
ELEPHANT
0=ELEPHANT
JUMP
1=JUMP
LOOP
2=LOOP
象棋
跳棋
圍棋

※Enum的建構子


public enum Chess {
    ELEPHANT("象棋"), JUMP("跳棋"), LOOP("圍棋");
    Chess(String chessName) {//建構子會自動轉為private,可以不寫private
        this.setChessName(chessName);
    }

    String chessName;

    public String getChessName() {
        return chessName;
    }

    public void setChessName(String chessName) {
        this.chessName = chessName;
    }
}

呼叫建構子沒什麼特別
for (Chess chess : Chess.values()) {
    System.out.println(chess.ordinal() + "=" + chess.name() + "=" + chess.getChessName());
}

結果:
0=ELEPHANT=象棋
1=JUMP=跳棋
2=LOOP=圍棋

※其他


轉換成Enum
Chess chess = Enum.valueOf(Chess.class, "JUMP");//注意大小寫,第二個參數是使用Chess.name的回傳值
chess.setChessName("我跳");
System.out.println(chess.getChessName());

排序
Set<Chess> set = new TreeSet<>();
set.add(Chess.LOOP);
set.add(Chess.JUMP);
set.add(Chess.ELEPHANT);
Iterator<Chess> it = set.iterator();
while(it.hasNext()){
    System.out.println(it.next() + " ");
}

implement interface

interface Msg {
    public String getInfo();
}

public class TestEnum {
    public enum Chess implements Msg {
        ELEPHANT {
            @Override
            public String getInfo() {
                return "象棋";
            }
        },
        JUMP {
            @Override
            public String getInfo() {
                return "跳棋";
            }
        },
        LOOP {
            @Override
            public String getInfo() {
                return "圍棋";
            }
        };
    }

    public static void main(String[] args) {
        for (Chess chess : Chess.values()) {
            System.out.print(chess + "=" + chess.getInfo() + " ");
        }
    }
}

上面的程式碼也可以不implement,用abstract也可以
public enum Chess {
    ELEPHANT {
        @Override
        public String getInfo() {
            return "象棋";
        }
    },
    JUMP {
        @Override
        public String getInfo() {
            return "跳棋";
        }
    },
    LOOP {
        @Override
        public String getInfo() {
            return "圍棋";
        }
    };
    public abstract String getInfo();
}

※使用EnumMap


import java.util.EnumMap;
import java.util.Map;

public class TestEnumMap {
    public enum Chess {
        ELEPHANT, JUMP, LOOP;
    }

    public static void main(String[] args) {
        //Map<Chess, String> map = new TreeMap<>();//使用這行結果也是完全一樣
        Map<Chess, String> map = new EnumMap<>(Chess.class);
        map.put(Chess.ELEPHANT, "象棋");
        map.put(Chess.JUMP, "跳棋");
        map.put(Chess.LOOP, "圍棋");

        // 取key
        for (Chess chess : map.keySet()) {
            System.out.print(chess.name() + " ");
        }
        System.out.println();
        
        // 取value
        for (String value : map.values()) {
            System.out.print(value + " ");
        }
        System.out.println();

        // 取key=value
        for (Chess chess : Chess.values()) {
            System.out.println(chess.name() + "=" + map.get(chess));
        }
    }
}

※使用EnumSet

public class TestEnumSet {
    public enum Chess {
        ELEPHANT, JUMP, LOOP;
    }

    public static void main(String[] args) {
        //allOf:將Enum的值全抓進來
        for(Chess chess:EnumSet.allOf(Chess.class)){
            System.out.println(chess);
        }
        System.out.println();
        //of:只抓特定的Enum
        for(Chess chess:EnumSet.of(Chess.ELEPHANT)){
            System.out.println(chess);
        }
        System.out.println();
        //of:只抓特定的Enum,為overloading
        for(Chess chess:EnumSet.of(Chess.ELEPHANT, Chess.JUMP)){
            System.out.println(chess);
        }
        System.out.println();
        //noneOf:創建一個空的、特定的Enum
        EnumSet<Chess> es = EnumSet.noneOf(Chess.class);
        es.add(Chess.LOOP);
        for(Chess chess:es){
            System.out.println(chess);
        }
        System.out.println();
        //complementOf:取目前已有的Enum的值,然後取反
        for(Chess chess:EnumSet.complementOf(es)){
            System.out.println(chess);
        }
        System.out.println();
        //copyOf:複製Enum
        for(Chess chess:EnumSet.copyOf(es)){
            System.out.println(chess);
        }
        System.out.println();
        //clone:複製Enum
        for(Chess chess:es.clone()){
            System.out.println(chess);
        }
    }
}

沒有留言:

張貼留言