提要:
1.枚举类型介绍与简单使用
2.枚举类型中常用的方法
3.枚举类型嵌套
4.EnumSet与EnumMap
1.枚举类型介绍与简单使用
public enum Test{
T1("1"),T2("2");
static String s1 = "s1";
static String s2 = "s2";
Test(String s){
System.out.println(s);
print();
}
public static void plus(){
System.out.println(s1 + s2);
}
private void print(){
System.out.printf("%s,%s\n",s1,s2);
}
}
public static void main(String[] args){
Test test = Test.T1;
test.plus();
switch (test) {
case T1 :
System.out.println(true);
break;
default :
System.out.println(true);
break;
}
}
----------------------------
输出结果:
1
null,null
2
null,null<pre name="code" class="java">s1s2
true
之所以会是null是因为static变量直到它所属的类第一次被加载时才会被加载,这里只是编译并没有使用,类没有被加载
2.枚举类型中常用的方法
- 调用values()方法,可以遍历enum实例。
- 调用toString()方法,可以打印枚举实例的名称。
- 调用valueOf()方法,可以根据名字获得枚举实例。
- 调用ordinal()方法,可以取得枚举实例的次序。
public class Test {
public enum Fruit{
APPLE,ORANGE,TOMATO;
}
public static void main(String[] args){
for(Fruit fruit : Fruit.values()){
System.out.println(fruit.toString() + " is on " + fruit.ordinal());
}
System.out.println("It's " + Fruit.valueOf("APPLE").toString());
}
}
------------------------------------
输出:
APPLE is on 0
ORANGE is on 1
TOMATO is on 2
It's APPLE
3.枚举类型嵌套
Food:{
DESSERT:{VEGETABLES, CAPCAKE},
COFFEE:{LATEE, TEA}
}
或许我可以建一个这样的枚举?
public class Test{
enum Food{
DESSERT(Dessert.class), COFFEE(Coffee.class);
private Enum[] food;
private Food(Class<?> eclass) {
this.food = (Enum[]) eclass.getEnumConstants();
}
public Enum[] getFood(){
return food;
}
}
enum Dessert{
VEGETABLES, CAPCAKE
}
enum Coffee{
LATTE, TEA
}
public static void main(String args[]) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
Enum[] enums = Food.DESSERT.getFood();
for(Enum e : enums){
System.out.println(e.ordinal());
System.out.println(e.toString());
}
}
}
重点在于Class的getEnumConstants方法,该方法专用于枚举类型,返回其枚举实例。但这种方式并没有直观的组织化,Dessert和Coffee并没有在语法上归为同一类,Food的枚举实例也可以接受除了这两个枚举之外的任何枚举类型参数。因此考虑用interface作为中介,使Dessert和Coffee实现同一个接口,并且Food只接受这个接口的实现类:
public class Test{
public interface FoodIntef{
public enum Dessert implements FoodIntef{
VEGETABLES, CAPCAKE
}
public enum Coffee implements FoodIntef{
LATTE, TEA
}
}
public enum Food{
DESSERT(FoodIntef.Dessert.class), COFFEE(FoodIntef.Coffee.class);
private FoodIntef[] food;
private Food(Class<? extends FoodIntef> food){
this.food = food.getEnumConstants();
}
}
}
4.EnumSet和EnumMap
EnumSet是专用于存储枚举类型的set,其中的所有键都必须来自同一个枚举类型。枚举实例在EnumSet内部以位向量的形式存储,因此非常紧凑和高效。
和大多数集合类一样,EnumSet是不同步的。
EnumSet通过自身的多个静态方法创建实例。其中EnumSet有多个重载的of方法,在枚举实例个数为2~5个时候都可以使用固定参数的of方法,超过5个则使用可变参数的of方法,这样做的原因是可变参数对比显式的参数,在性能上会有一点损失。
EnumSet的底层实现是long,一个long值占64位空间,而一个enum实例只需一个bit位表示其是否存在,如果enum元素多过64个bit,EnumSet会用一个
new long[(universe.length + 63) >>> 6]
EnumMap用来自同一个枚举类型的枚举实例作为键,除了键只能是枚举类型这一个限制,其他跟Map差不多。
EnumMap在内部表现为数组。