平常不怎麼使用 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;
}
}
|