枚举类型 :枚举常量的一组集合,包含者一些操作方法,枚举类是不可变的,通常用作单实例操作。
包含的方法
自带静态方法 values() 返回枚举类中枚举常量数组 (按枚举常量声明的顺序返回)
toString()方法 返回枚举常量名称。
静态方法valueOf(String name) 返回指定名称(name指的是默认toString方法返回的值,即类型常量的名称)的枚举常量
ordinal() 返回指定枚举常量在枚举类型中声明的位置,位置从0开始哦
枚举类型中 每一个枚举常量都要实现,枚举类中的抽象方法,枚举常量就是一个静态变量。因此下面代码枚举类型常量需要放在自定义静态代码块之前
案例如下:
package com.effectJava.Chapter3; import java.util.HashMap; import java.util.Map; public enum Operation { PLUS("+") { @Override int apply(int a, int b) { return a + b; } }, MINUS("-") { @Override int apply(int a, int b) { return a - b; } }, MULTI("*") { @Override int apply(int a, int b) { return a * b; } }, DIVID("/") { @Override int apply(int a, int b) {//测试代码没必要处理可能的异常 return a / b; } }; // 自定义的valueOf方法 private static final Map<String, Operation> maps; static { System.out.println("Initi Static Block"); maps = new HashMap<>(); for (Operation operation : Operation.values()) { maps.put(operation.symbol, operation); } } public static Operation fromString(String symbol) { return maps.get(symbol); } private final String symbol; Operation(String symbol) { System.out.println(symbol); this.symbol = symbol; } abstract int apply(int a, int b); // 把symbol变为枚举常量的唯一标识后,
//最好定义一个fromString(String symbol)方法返回symbol唯一标识的枚举类型 public static void main(String... args) { System.out.println(Operation.PLUS.apply(1, 2)); // Operation.valueOf("ss"); System.out.println(Operation.fromString("+")); } }
java 程序初始化顺序
1.父类静态变量 2.父类静态代码块 3.子类静态变量 4.子类静态代码块 5.父类非静态变量 6.父类非静态代码块,7.父类构造器,8.子类非静态变量 9.子类非静态代码块 10.子类构造器
序列索引实现香草分类
package com.effectJava.Chapter3; import sun.misc.SharedSecrets; import java.util.EnumMap; import java.util.HashSet; import java.util.Set; public class Herb { public enum Type {ANNUAL, PERENNIAL, BIENNIAL,} private final String name; private final Type type; Herb(String name, Type type) { this.name = name; this.type = type; } @Override public String toString() { return name; } // 对植物进行分类 public static void main(String... args) { Herb herbs[] = new Herb[]{new Herb("herb1", Type.PERENNIAL), new Herb("herb2", Type.ANNUAL), new Herb("herb3", Type.ANNUAL), new Herb("herb4", Type.BIENNIAL)}; //1.通过枚举常量的位置序号来对植物的类别分类位置 // 构造类别数组 Set<Herb>[] her = (Set<Herb>[]) new Set[Type.values().length]; for (int i = 0; i < her.length; i++) { her[i] = new HashSet<Herb>(); } // 对植物进行分类 for (Herb herb : herbs) { her[herb.type.ordinal()].add(herb); } for (int i = 0; i < her.length; i++) { System.out.printf("%s : %s%n", Herb.Type.values()[i], her[i]); } System.out.println(SharedSecrets.getJavaLangAccess().getEnumConstantsShared(Type.class));
//EnumMap分类 对每种香草分类, // 2. 使用EnumMap来实现植物分类 System.out.println(" 使用EnumMap来实现植物分类"); EnumMap<Type, Set<Herb>> typeSetEnumMap = new EnumMap<>(Type.class); for (Herb.Type t : Herb.Type.values()) { typeSetEnumMap.put(t, new HashSet<Herb>()); } for (Herb h : herbs) { typeSetEnumMap.get(h.type).add(h); } System.out.println(typeSetEnumMap); } }
EnumMap状态转移两种实现
package com.effectJava.Chapter3; //转移关系 public enum Phase { SOLID, LIQUID, GAS; public enum Transition { MELT, FREEZE, BOIL, CONDENSE, SUBLIME, DEPOSIT; private static final Transition[][] transitions = {{null, MELT, SUBLIME}, {FREEZE, null, BOIL}, {DEPOSIT, CONDENSE, null}}; public static Transition from(Phase src, Phase dest) { return transitions[src.ordinal()][dest.ordinal()]; } } }
优化之后的代码
package com.effectJava.Chapter3; import java.util.EnumMap; import java.util.Map; //通过 Map<起始阶段,Map<目标阶段,阶段过渡>> 来表示转移关系 public enum PhaseModify { SOLID,LIQUID,GAS; public enum Transition { MELT(SOLID, LIQUID), FREEZE(LIQUID, SOLID), BOIL(LIQUID, GAS), CONDENSE(GAS, LIQUID), SUBLIME(SOLID, GAS), DEPOSIT(GAS, SOLID); private final PhaseModify src; private final PhaseModify dst; Transition(PhaseModify src, PhaseModify dst) { this.src = src; this.dst = dst; } private static final Map<PhaseModify, Map<PhaseModify, Transition>> map = new EnumMap<PhaseModify, Map<PhaseModify, Transition>>(PhaseModify.class); static { for (PhaseModify p : PhaseModify.values()) { map.put(p, new EnumMap<PhaseModify, Transition>(PhaseModify.class)); } for (Transition trans : Transition.values()) { map.get(trans.src).put(trans.dst, trans); } } public static Transition from(Phase src, Phase dst) { return map.get(src).get(dst); } } }