一、Enum枚举
public enum Day {
MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}
一个简单的测试类:
public class TestEnum {
public static void main(String[] args) {
Day today=Day.FRIDAY;
switch(today)
{
case MONDAY:
System.out.println("today is monday");
break;
case TUESDAY:
System.out.println("today is tuesday");
break;
case WEDNESDAY:
System.out.println("today is webnesday");
break;
case THURSDAY:
System.out.println("today is thursday");
break;
case FRIDAY:
System.out.println("today is firday");
break;
case SATURDAY:
System.out.println("today is saturday");
break;
case SUNDAY:
System.out.println("today is sunday");
break;
}
}
}
测试结果:
today is firday
Day枚举的本质就是一个类,编译器会自动为我们生成Day类,通过反编译得到该类如下:
final class Day extends Enum
{
//编译器为我们添加的静态的values()方法
public static Day[] values()
{
return (Day[])$VALUES.clone();
}
//编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法
public static Day valueOf(String s)
{
return (Day)Enum.valueOf(com/zejian/enumdemo/Day, s);
}
//私有构造函数
private Day(String s, int i)
{
super(s, i);
}
//前面定义的7种枚举实例
public static final Day MONDAY;
public static final Day TUESDAY;
public static final Day WEDNESDAY;
public static final Day THURSDAY;
public static final Day FRIDAY;
public static final Day SATURDAY;
public static final Day SUNDAY;
private static final Day $VALUES[];
static
{
//实例化枚举实例
MONDAY = new Day("MONDAY", 0);
TUESDAY = new Day("TUESDAY", 1);
WEDNESDAY = new Day("WEDNESDAY", 2);
THURSDAY = new Day("THURSDAY", 3);
FRIDAY = new Day("FRIDAY", 4);
SATURDAY = new Day("SATURDAY", 5);
SUNDAY = new Day("SUNDAY", 6);
$VALUES = (new Day[] {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
});
}
}
可以清楚地看出每个枚举类型即星期数就是该Day类的一个实例对象,该构成方式和单例模式有些类似,故可以用只有一个枚举类型的枚举作为单例模式,而且枚举的构造器由编译器管理安全性十分高,既可以防止反射破解也可以防止反序列破解。
Day类继承了Enum类,下面看下Enum代码,可以更好理解枚举的方法:
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
private final String name; //枚举字符串名称
public final String name() {
return name;
}
private final int ordinal;//枚举顺序值
public final int ordinal() {
return ordinal;
}
//枚举的构造方法,只能由编译器调用
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
public String toString() {
return name;
}
public final boolean equals(Object other) {
return this==other;
}
//比较的是ordinal值
public final int compareTo(E o) {
Enum> other = (Enum>)o;
Enum self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;//根据ordinal值比较大小
}
@SuppressWarnings("unchecked")
public final Class getDeclaringClass() {
//获取class对象引用,getClass()是Object的方法
Class> clazz = getClass();
//获取父类Class对象引用
Class> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class)clazz : (Class)zuper;
}
public static > T valueOf(Class enumType,
String name) {
//enumType.enumConstantDirectory()获取到的是一个map集合,key值就是name,value则是枚举变量值
//enumConstantDirectory是class对象内部的方法,根据class对象获取一个map集合的值
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
//.....省略其他没用的方法
}
二、EnumMap
public class TestEnumMap {
public static void main(String[] args) {
Day today=Day.FRIDAY;
EnumMap enummap=new EnumMap(Day.class); //对应Day类的EnumMap
enummap.put(Day.MONDAY, "work work"); //第一个值为key不能为null,第二个值为values可以为null
enummap.put(Day.TUESDAY, "work work"); //第一个值填入枚举实例,第二个值为该枚举实例的记录信息
enummap.put(Day.WEDNESDAY, "work work");
enummap.put(Day.THURSDAY, "work work");
enummap.put(Day.FRIDAY, "work work");
enummap.put(Day.SATURDAY, "have fun");
enummap.put(Day.SUNDAY, "have fun");
System.out.println(enummap);
String job=(String) enummap.get(today); //用get方法输入key值获得今天的工作信息
System.out.println("job is:"+job);
}
}
输出结果为:
{MONDAY=work work, TUESDAY=work work, WEDNESDAY=work work, THURSDAY=work work, FRIDAY=work work, SATURDAY=have fun, SUNDAY=have fun}
job is:work work
这个例子很清晰展示了EnumMap的基本用法
三、EnumSet
1.noneOf创建空队列
public class TestEnumSet {
public static void main(String[] args) {
EnumSet enumset=EnumSet.noneOf(Day.class);//创建一个空的Day枚举类型的队列
System.out.println("Before:"+enumset); //添加元素前状态
enumset.add(Day.MONDAY); //添加三个元素
enumset.add(Day.TUESDAY);
enumset.add(Day.WEDNESDAY);
System.out.println("After:"+enumset); //添加元素后状态
}
}
运行结果:
Before:[]
After:[MONDAY, TUESDAY, WEDNESDAY]
2.allOf创建满队列
public class TestEnumSet {
public static void main(String[] args) {
EnumSet enumset=EnumSet.allOf(Day.class);
System.out.println(enumset);
}
}
运行结果:
[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]
3.range创建指定范围队列
public class TestEnumSet {
public static void main(String[] args) {
EnumSet enumset=EnumSet.range(Day.MONDAY, Day.FRIDAY);
System.out.println(enumset);
}
}
运行结果:
[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
4.complementOf补集创建队列
public class TestEnumSet {
public static void main(String[] args) {
EnumSet enumset1=EnumSet.range(Day.MONDAY, Day.FRIDAY);
System.out.println("enumset1:"+enumset1);
EnumSet enumset2=EnumSet.complementOf(enumset1);//创建enumset1的补集enumset2
System.out.println("enumset2:"+enumset2);
}
}
运行结果:
enumset1:[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
enumset2:[SATURDAY, SUNDAY]
5.copyOf复制创建
public class TestEnumSet {
public static void main(String[] args) {
EnumSet enumset1=EnumSet.range(Day.MONDAY, Day.FRIDAY);
System.out.println("enumset1:"+enumset1);
EnumSet enumset2=EnumSet.copyOf(enumset1);//复制enumset1创建enumset2
System.out.println("enumset2:"+enumset2);
}
}
运行结果:
enumset1:[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
enumset2:[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
6.copyOf复制ArrayList创建
public class TestEnumSet {
public static void main(String[] args) {
ArrayList list=new ArrayList();
list.add(Day.MONDAY);
list.add(Day.TUESDAY);
list.add(Day.WEDNESDAY);
list.add(Day.WEDNESDAY);
System.out.println("list:"+list);
EnumSet enumset=EnumSet.copyOf(list);
System.out.println("enumset:"+enumset);
}
}
运行结果:
list:[MONDAY, TUESDAY, WEDNESDAY, WEDNESDAY]
enumset:[MONDAY, TUESDAY, WEDNESDAY]
通过结果可以看出ArrayList内放置的元素可以重复,而EnumSet内放置的元素不重复,毕竟是枚举列嘛