平常不怎麼使用 Enum ,非常地不熟悉,今天剛好用到,順便記錄一下。
簡單使用
| 1
2
3
 | public enum Action {
    STOP, RIGHT, LEFT, UP, DOWN
}
 | 
 
這邊簡單可以看到
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
 |     public static void play(int action) {
        switch(action) {
            case Action.STOP:
                System.out.println("播放停止動畫");
                break;
            略...
            default:
                System.out.println("不支援此動作");
        }
    }
 | 
 
以前抄抄範例,這邊會發現int action
怎麼會跑出 int 出來?
其實 Enum 反編譯出來,會跟原本 Enum 出來不一樣
不知道這算不算是 Java 語法糖?
| 1
2
3
4
5
6
7
8
9
 |     略...
    static {
        STOP = new Action("STOP", 0);
        RIGHT = new Action("RIGHT", 1);
        LEFT = new Action("LEFT", 2);
        UP = new Action("UP", 3);
        DOWN = new Action("DOWN", 4);
        略...
    }
 | 
 
詳細內容可以看:使用 enum 列舉常數
自定一些內容
我們公司使用不單是這樣
可以設定出
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 | public enum Car {
    MAX_CAR(100,"最高級車"), NORM_CAR(5,"中級車"), MIN_CAR(1,"低級車"); 
    
    private int price;
    private String desc;
    
    private Car(int price, String desc) {
        this.price = price;
        this.desc = desc;
    }
    public int price() {
        return price;
    }
    
    public String desc() {
        return desc;
    }
    
    public static void main(String[] args) {
        for(Car car : Car.values()) {
            System.out.printf("Car(%s, %d, %s)%n",
                  car , car.price() , car.desc());
        }
    }
}
 | 
 
這邊看到會對印到 MAX_CAR(100,"最高級車"), NORM_CAR(5,"中級車"), MIN_CAR(1,"低級車"); 
| 1
2
3
4
 |     private Car(int price, String desc) {
        this.price = price;
        this.desc = desc;
    }
 | 
 
其他詳細可看:進階 enum 運用
取出列表資料(values)
| 1
2
3
 | for(Car car: Car.values())
    System.out.println(car.name());
}
 | 
 
.values() 可以印出列表出來
那有沒有find 呢?
目前看應該只能用迴圈滾…
轉成陣列方法
You can do (pre-Java 8):
| 1
 | List<Enum> enumValues = Arrays.asList(Enum.values());
 | 
 
or
| 1
 | List<Enum> enumValues = new ArrayList<Enum>(EnumSet.allOf(Enum.class));
 | 
 
Using Java 8 features, you can map each constant to its name:
| 1
2
3
 | List<String> enumNames = Stream.of(Enum.values())
                               .map(Enum::name)
                               .collect(Collectors.toList());
 | 
 
Java: Check if enum contains a given string? - Stack Overflow
This should do it:
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
 | public static boolean contains(String test) {
    for (Choice c : Choice.values()) {
        if (c.name().equals(test)) {
            return true;
        }
    }
    return false;
}
 | 
 
This way means you do not have to worry about adding additional enum values later, they are > all checked.
Edit: If the enum is very large you could stick the values in a HashSet:
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
 | public static HashSet<String> getEnums() {
  HashSet<String> values = new HashSet<String>();
  for (Choice c : Choice.values()) {
      values.add(c.name());
  }
  return values;
}
 | 
 
Then you can just do: values.contains(“your string”) which returns true or false.
values() 神奇 method 實作方法
參考: Java Enum - javatpoint
原理 static 放 $VALUES 陣列變數,使用values() 會傳 $VALUES 陣列變數 ,就可以 foreach 比較。
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 |     final class Season extends Enum  
    {  
        public static Season[] values()  
        {  
            return (Season[])$VALUES.clone();  
        }  
        public static Season valueOf(String s)  
        {  
            return (Season)Enum.valueOf(Season, s);  
        }  
        private Season(String s, int i, int j)  
        {  
            super(s, i);  
            value = j;  
        }  
        public static final Season WINTER;  
        public static final Season SUMMER;  
        private int value;  
        private static final Season $VALUES[];  
        static   
        {  
            WINTER = new Season("WINTER", 0, 10);  
            SUMMER = new Season("SUMMER", 1, 20);  
            $VALUES = (new Season[] {  
                WINTER, SUMMER  
            });  
        }  
    }  
 | 
 
其他之後有遇到再補
2020-06-18
特別載入環境變數方法
最近做 Enum 發現測試環境跟正式環境設定的值會不一樣,所以找一下有什麼方法可以解決這個問題。
目前這邊還沒測試能不能這樣用。
java property file as enum - Stack Overflow
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 | public enum Constants {
    PROP1,
    PROP2;
    private static final String PATH            = "/constants.properties";
    private static final Logger logger          = LoggerFactory.getLogger(Constants.class);
    private static Properties   properties;
    private String          value;
    private void init() {
        if (properties == null) {
            properties = new Properties();
            try {
                properties.load(Constants.class.getResourceAsStream(PATH));
            }
            catch (Exception e) {
                logger.error("Unable to load " + PATH + " file from classpath.", e);
                System.exit(1);
            }
        }
        value = (String) properties.get(this.toString());
    }
    public String getValue() {
        if (value == null) {
            init();
        }
        return value;
    }
}
 | 
 
enum 裡面帶 method 方法
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 |  //1.提供当前枚举类的对象,多个对象之间用逗号隔开,末尾对象分号结束
   SPRING ("春天","春暖花开"){
        @Override
        public void show() {
            System.out.println("spring!!!");
        }
    },
   SUMMER("夏天","夏日炎炎"){
       @Override
       public void show() {
           System.out.println("summer!!!");
       }
   },
   AUTUMN ("秋天","秋高气爽"){
       @Override
       public void show() {
           System.out.println("autumn!!!");
       }
   },
   WINTER ("冬天","冰天雪地"){
       @Override
       public void show() {
           super.show();
           System.out.println("winter!!!");
       }
   };
 | 
 
參考: java枚举和注解 - 知乎
實用範例
方便以後直接找 sample code 來用,畢竟真的不常寫,很容易要想怎麼寫。
最佳範例: 菜鳥工程師 肉豬: Java 列舉(Enum)範例
還是推薦看裡面內容。
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 | public enum WeekDay {
    SUN("Sunday","星期日", 0),
    MON("Monday","星期一", 1),
    TUE("Tuesday","星期二", 2),
    WED("Wednesday","星期三", 3),
    THU("Thursday","星期四", 4), 
    FRI("Friday","星期五", 5),
    SAT("Saturday","星期六", 6);
    WeekDay(String day, String chinese, int code){
        this.day = day;
        this.chinese = chinese;
        this.code = code;
    }
    private final String day;
    private final String chinese;
    private int code;
    public static WeekDay getWeek(int i){
        for(WeekDay weekDay : values()){
            if(weekDay.getCode() == i) {
                return weekDay;
            }
        }
        return null;
    }
    public String getDay(){
        return this.day;
    }
    
    public String getChinese() {
        return this.chinese;
    }
    public int getCode() {
        return this.code;
    }
  
}
 |