一篇java中的枚举Enum
1.基本语法
定义一个Week枚举
public enum Week implements I<Integer>{
MONDAY,TUESDAY,WEDNEDDAY,THURSDAY,FIRDAY,SATURDAT,SUNDAY;
@Override
public void c() {
}
}
对其反编译 Javap
Compiled from "Week.java"
public final class Week extends java.lang.Enum<Week> implements I<java.lang.Integer> {
public static final Week MONDAY;
public static final Week TUESDAY;
public static final Week WEDNEDDAY;
public static final Week THURSDAY;
public static final Week FIRDAY;
public static final Week SATURDAT;
public static final Week SUNDAY;
//编译器添加
public static Week[] values();
//编译器添加
public static Week valueOf(java.lang.String);
public void c();
static {};
}
2.特性
- 默认final private
- 继承Enum类
- 使用switch,case没有覆盖全部enum实例,编译器不会报错,应定义default,使其程序可控
- Enum实现Comparable接口,根据ordinal来比较
3.常用方法
public final String name()
返回定义名称public final int ordinal()
返回定义顺序public static T[] values();
返回定义的所有enum实例枚举public static T valueOf(java.lang.String);
根据名称获取实例。使用==判断为true
4.其他常用方法
- Class类方法
public T[] getEnumConstants()
作用等同values()。但自定义枚举向上转型后无法使用values方法,可以使用此方法
5.实用代码
//选自think in java 19.6
- 随机选择
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)];
}
} ///:~
- 使用接口组织枚举
public interface Food {
enum Appetizer implements Food {
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOO;
}
enum Dessert implements Food {
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
FRUIT, CREME_CARAMEL;
}
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,
LATTE, CAPPUCCINO, TEA, HERB_TEA;
}
} ///:~
- 枚举的枚举
import utils.Enums;
public enum Course {
APPETIZER(Food.Appetizer.class),
MAINCOURSE(Food.MainCourse.class),
DESSERT(Food.Dessert.class),
COFFEE(Food.Coffee.class);
private Food[] values;
private Course(Class<? extends Food> kind) {
values = kind.getEnumConstants();
}
public Food randomSelection() {
return Enums.random(values);
}
} ///:~
6.集合
-
EnumSet
- 对相同参数调用add会被忽略掉
- 添加实例的顺序由定义Enum时的顺序决定
-
EnumMap
-
普通多路分发
//: enumerated/Competitor.java // Switching one enum on another. import I.Outcome; public interface Competitor<T extends Competitor<T>> { Outcome compete(T competitor); } ///:~ //: enumerated/RoShamBo.java // Common tools for RoShamBo examples. package utils; import java.util.Random; 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)]; } } ///:~ import utils.Enums; 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)); } } ///:~ package I;//: enumerated/Outcome.java public enum Outcome { WIN, LOSE, DRAW } ///:~ import I.Outcome; import static I.Outcome.*; 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) { this.vPAPER = paper; this.vSCISSORS = scissors; this.vROCK = rock; } public Outcome compete(RoShamBo2 it) { switch(it) { default: case PAPER: return vPAPER; case SCISSORS: return vSCISSORS; case ROCK: return vROCK; } } public static void main(String[] args) { RoShamBo.play(RoShamBo2.class, 20); }
-
使用EnumMap实现多路分发
import java.util.*; import static enumerated.Outcome.*; 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, DRAW, LOSE, WIN); initRow(SCISSORS, WIN, DRAW, LOSE); initRow(ROCK, LOSE, WIN, 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); } public Outcome compete(RoShamBo5 it) { return table.get(this).get(it); } public static void main(String[] args) { RoShamBo.play(RoShamBo5.class, 20); } } /* Same output as RoShamBo2.java *///:~
3.使用二维数组分发
import static enumerated.Outcome.*; enum RoShamBo6 implements Competitor<RoShamBo6> { PAPER, SCISSORS, ROCK; private static Outcome[][] table = { { DRAW, LOSE, WIN }, // PAPER { WIN, DRAW, LOSE }, // SCISSORS { LOSE, WIN, DRAW }, // ROCK }; public Outcome compete(RoShamBo6 other) { return table[this.ordinal()][other.ordinal()]; } public static void main(String[] args) { RoShamBo.play(RoShamBo6.class, 20); } } ///:~
-
-