java.lang.Enumvalues()、valueOf(String) 靜態方法final 類,不可被繼承
enum Shrubbery { GROUND, CRAWLING, HANGING }
for (Shrubbery s : Shrubbery.values()) {
System.out.println(s + " ordinal: " + s.ordinal());
System.out.println(s.compareTo(Shrubbery.CRAWLING));
System.out.println(s == Shrubbery.CRAWLING); // 枚舉比較用 == 安全
System.out.println(s.getDeclaringClass());
System.out.println(s.name());
}
// 字符串轉枚舉
Shrubbery s = Enum.valueOf(Shrubbery.class, "HANGING");
// 靜態導入簡化調用
import static enumerated.Spiciness.*;
public class Burrito {
Spiciness degree;
public Burrito(Spiciness degree) { this.degree = degree; }
}
// 向枚舉添加方法、構造器、字段
public enum OzWitch {
WEST("Miss Gulch"), NORTH("Glinda"), EAST("Wicked"), SOUTH("Good");
private final String description;
private OzWitch(String desc) { this.description = desc; }
public String getDescription() { return description; }
public static void main(String[] args) {
for (OzWitch w : values())
System.out.println(w + ": " + w.getDescription());
}
}
// 覆寫 toString()
public enum SpaceShip {
SCOUT, CARGO, BATTLESHIP;
public String toString() {
String id = name();
return id.charAt(0) + id.substring(1).toLowerCase();
}
}
enum Signal { GREEN, YELLOW, RED }
public class TrafficLight {
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;
}
}
}
case 標簽直接使用枚舉常量名,無需前綴類名。
values():編譯器生成的靜態方法,返回聲明順序數組valueOf(String):編譯器生成單參數版本;Enum.valueOf(Class, String) 為雙參數基礎版本Enum 後 values() 不可用,改用 Class.getEnumConstants()
// 接口內嵌套枚舉分組
public interface Food {
enum Appetizer implements Food { SALAD, SOUP }
enum MainCourse implements Food { LASAGNE, BURRITO }
enum Dessert implements Food { TIRAMISU, GELATO }
}
// 統一類型引用
Food food = Appetizer.SALAD;
food = MainCourse.LASAGNE;
// 枚舉封裝枚舉:隨機選餐
public enum Course {
APPETIZER(Food.Appetizer.class), MAIN_COURSE(Food.MainCourse.class);
private final Food[] values;
Course(Class extends Food> clazz) { values = clazz.getEnumConstants(); }
public Food randomSelection() { return Enums.random(values); }
}
enum AlarmPoints { STAIR1, STAIR2, LOBBY, OFFICE1, KITCHEN }
EnumSet set = EnumSet.noneOf(AlarmPoints.class);
set.add(STAIR1);
set.addAll(EnumSet.of(LOBBY, KITCHEN));
set.removeAll(EnumSet.range(OFFICE1, OFFICE4));
EnumSet complement = EnumSet.complementOf(set);
// 內部用 long 位向量,64位以內單 long,超過自動擴展為 long[]
// 性能遠優於 HashSet,類型安全
EnumMap map = new EnumMap<>(AlarmPoints.class);
map.put(KITCHEN, () -> System.out.println("Kitchen fire!"));
map.put(BATHROOM, () -> System.out.println("Bathroom alert!"));
for (Map.Entry e : map.entrySet()) {
e.getValue().action();
}
// 內部用數組實現,O(1) 訪問,無哈希計算、無裝箱
public enum ConstantSpecificMethod {
DATE_TIME { String getInfo() { return new Date().toString(); } },
CLASSPATH { String getInfo() { return System.getenv("CLASSPATH"); } },
VERSION { String getInfo() { return System.getProperty("java.version"); } };
abstract String getInfo();
}
// 等價於為每個常量創建匿名內部類繼承枚舉基類
// 但枚舉常量不是獨立類型,不能作參數類型
enum MailHandler {
GENERAL_DELIVERY { boolean handle(Mail m) { ... } },
MACHINE_SCAN { boolean handle(Mail m) { ... } },
VISUAL_INSPECTION { boolean handle(Mail m) { ... } },
RETURN_TO_SENDER { boolean handle(Mail m) { ... } };
abstract boolean handle(Mail m);
}
static void handle(Mail m) {
for (MailHandler h : MailHandler.values())
if (h.handle(m)) return;
System.out.println(m + " is dead letter");
}
enum Input { NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100),
TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50),
ABORT_TRANSACTION, STOP; // 無金額特殊輸入
int value;
Input(int v) { value = v; }
Input() {}
int amount() { return value; }
}
enum Category {
MONEY(NICKEL, DIME, QUARTER, DOLLAR),
ITEM_SELECTION(TOOTHPASTE, CHIPS, SODA, SOAP);
private final Input[] values;
Category(Input... v) { values = v; }
private static final EnumMap MAP = new EnumMap<>(Input.class);
static { for (Category c : values()) for (Input i : c.values) MAP.put(i, c); }
public static Category categorize(Input i) { return MAP.get(i); }
}
enum State {
RESTING { void next(Input i) { switch(Category.categorize(i)) { case MONEY: amount+=i.amount(); state=ADDING_MONEY; break; ... } } },
ADDING_MONEY { void next(Input i) { ... } },
DISPENSING(TRANSIENT) { void next() { ... } },
GIVING_CHANGE(TRANSIENT) { void next() { ... } },
TERMINAL { void output() { System.out.println("Halted"); } };
boolean isTransient = false;
State() {}
State(StateDuration d) { isTransient = true; }
abstract void next(Input i);
abstract void next();
void output() { System.out.println(amount); }
}
enum RoShamBo5 implements Competitor {
PAPER, SCISSORS, ROCK;
static final EnumMap> TABLE = new EnumMap<>(RoShamBo5.class);
static {
for (RoShamBo5 r : values()) TABLE.put(r, new EnumMap<>(RoShamBo5.class));
initRow(PAPER, DRAW, LOSE, WIN);
initRow(SCISSORS, WIN, DRAW, LOSE);
initRow(ROCK, LOSE, WIN, DRAW);
}
static void initRow(RoShamBo5 r, Outcome... o) {
EnumMap row = TABLE.get(r);
row.put(PAPER, o[0]); row.put(SCISSORS, o[1]); row.put(ROCK, o[2]);
}
public Outcome compete(RoShamBo5 other) { return TABLE.get(this).get(other); }
}
enum RoShamBo6 implements Competitor {
PAPER, SCISSORS, ROCK;
private static final Outcome[][] TABLE = {
{ DRAW, LOSE, WIN }, // PAPER
{ WIN, DRAW, LOSE }, // SCISSORS
{ LOSE, WIN, DRAW } // ROCK
};
public Outcome compete(RoShamBo6 other) { return TABLE[ordinal()][other.ordinal()]; }
}
核心洞見:枚舉實例固定、有序、可作數組索引,使查找表/矩陣成為多重分派的高性能實現。