一。基本enum(枚举)特征
0.创建枚举时编译器(javac 生成.class)会为我们生成一个相关的类,通过反编译该.class,我们可知道该类继承enum。查阅该enum(抽象类),enum实现了comparable 和serializable两个接口。
1.0定义:关键字enum 。我们自己定义的枚举
public enum Shrubbery {
GROUNG,CRAWLING
}
1.1 编译器为我们生成的相关类结构。
public final class Shrubbery extends Enum
{
// public static Shrubbery[] values()
{
return (Shrubbery[])$VALUES.clone();
}
//根据实例名获取实例
public static Shrubbery valueOf(String s)
{
return (Shrubbery)Enum.valueOf(Shrubbery, s);
}
//私有构造方法,这里调用了父类的构造方法,其中参数s对应了常量名,参数i代表枚举的一个顺序(这个顺序与枚举的声明顺序对应,用于oridinal()方法返回顺序值) private Shrubbery(String s, int i)
{
super(s, i);
}
//我们定义的枚举在这里声明了三个 ColorEnum的常量对象引用,对象的实例化在static静态块中 public static final Shrubbery GROUNG;
public static final Shrubbery CRAWLING;
//将所有枚举的实例存放在数组中 private static final Shrubbery $VALUES[];
static
{
GROUNG = new GROUNG("GROUNG", 0);
CRAWLING = new CRAWLING("GROUNG", 1)
//将所有枚举的实例存放在数组中 $VALUES = (new ColorEnum[] {
GROUNG,CRAWLING
});
}
}
1.2我们通过分析编译器为我们生成的类和其继承结构。我们可得到一些基本用法
1.2.1:values() 纯编译器生成可获取枚举常量数组。并且维护了我们定义时的顺序。
1.2.2: 定义的常量引用 我们可用 == 方法(比较效率更高)
1.2.3:分析继承结构 可用equals 和compareTo方法
。。。。。
二。枚举可像定义的常量一样 ,使用静态导入枚举 import static com.think.generic.enum19_1.Shrubbery.*;
2.1 结合switch语句,不需要case enum.* .
三。同过向枚举中添加一些新方法,可返回对枚举的一些表述
四。使用接口组织枚举:因为无法从enum继承子类,和编译器为我们从新定义了enum。
如何定义枚举的分类? 》〉在一个接口的内部定义,创建实现了该接口的枚举,(定义枚举的枚举)(枚举和接口的组合)
//分类泛型
public interface Food {
enum Appetizer implements Food{A1,A2,A3}
enum MainCourse implements Food{M1,M2,M3}
enum Coffer implements Food{C1,C2,C3}
}
//范型应用 需要定义构造 定义枚举的枚举
public enum Course {
//需要定义构造方法 The constructor Course(Class<Food.Coffer>) is undefined
APPETIZE(Food.Appetizer.class),
MainCourse(Food.MainCourse.class),
Coffer(Food.Coffer.class);
//定义返回值 枚举的枚举
private Food[] valuses;
//枚举的构造器返回的是泛型方法中的向上类型
// 构造方法
private Course(Class<? extends Food> food) {
Food[] enumConstants = food.getEnumConstants();
valuses = enumConstants;
}
public Food randomSelectiong() {
return EnumUtils.random(valuses);
}
}
创建一个枚举对象的工具类 随机返回
public class EnumUtils {
private static Random random = new Random(47);
public static <T extends Enum<T>> T random(Class<T> e) {
T[] enumConstants = e.getEnumConstants();
return random(enumConstants);
}
public static <T> T random(T[] values) {
T t = values[random.nextInt(values.length)];
return t;
}
}
另一种返回枚举的枚举 第一个枚举(Meal)里面是{APPETIZE,MainCourse,Coffer}
对应包含的枚举在 Food 接口中
public enum Meal {
APPETIZE(Food.Appetizer.class),
MainCourse(Food.MainCourse.class),
Coffer(Food.Coffer.class);
private Food[] valuses;
private Meal(Class<? extends Food> kind) {
valuses = kind.getEnumConstants();
}
public interface Food {
enum Appetizer implements Food{A1,A2,A3}
enum MainCourse implements Food{M1,M2,M3}
enum Coffer implements Food{C1,C2,C3}
}
public static void main(String[] args) {
for (Meal m : Meal.values()) {
System.out.println(m.name());
for (Food food : m.valuses) {
System.out.println(food);
}
System.out.println("------------");
}
}
}
五:EnumSets是一种set集合,该集合只能存放指定枚举类型(通过泛型制定)
public enum AlarmPoint {
START1,START2,LOBBY,OFFICE1,OFFICE2,OFFICE3,OFFICE4,BATHROOM,U TILITY,KITCHEN
}
使用案例
public class EnumSets {
public static void main(String[] args) {
//定义一个空的EnumSet集合
EnumSet<AlarmPoint> point = EnumSet.noneOf(AlarmPoint.class);
point.add(BATHROOM);
System.out.println(point);
point.addAll(EnumSet.of(START1, START2, KITCHEN));
System.out.println(point);
point = EnumSet.allOf(AlarmPoint.class);
System.out.println(point);
point.remove(START1);
System.out.println(point);
EnumSet<AlarmPoint> complementOf = EnumSet.complementOf(point);
System.out.println(complementOf);
}
}
六:EnumMap 是一种map集合,该集合中的key只能是制定枚举类型(通过泛型制定),案例是结合命令模式的用法,一般命令模式需要一个接口,该接口内部需要一个命令方法。
使用案例
interface Command {void action();}
public class EnumMaps {
public static void main(String[] args) {
EnumMap<AlarmPoint, Command> enumMap = new EnumMap<>(AlarmPoint.class);
enumMap.put(KITCHEN, new Command() {
@Override
public void action() {
System.out.println("厨房着火了");
}
});
enumMap.put(BATHROOM, new Command() {
@Override
public void action() {
System.out.println("浴室警报!!!");
}
});
//Set<Entry<AlarmPoint, Command>> entrySet = enumMap.entrySet();
for (Map.Entry<AlarmPoint, Command> entry : enumMap.entrySet()) {
System.out.println(entry.getKey());
entry.getValue().action();
}
//空指针异常
enumMap.get(OFFICE1).action();
}
}