枚举类型详解
一.Enum详解
1.1枚举类型的介绍
JDK1.5加入了一个全新的类型的”类”—枚举类型,为此JDK1.5引入了一个新的关键字enum,我们可以这样定义一个枚举类型。
Demo:一个最简单的枚举类
public enum ColorType {
RED, BLACK, YELLOW;
}
运行结果
class Testenum {
public static void main(String[] args) {
System.out.println(ColorType.BLACK);//BLACK
}
}
遍历枚举ColorType的所有值
public static void main(String[] args) {
//下面是for的增强循环方法,遍历枚举的所有值
for(ColorType color : ColorType.values()){
System.out.println(color);//RED BLACK YELLOW
}
}
1.2枚举类型的简单应用场景
描述一个人的状态:比如有以下状态SLEEP(睡觉),WORKING(工作),EATING(吃饭)
创建人的状态枚举类:
public enum PersonStatus {
SLEEP,WORKING,EATING;
}
打印出人的状态
public static void main(String[] args) {
showStatus(PersonStatus.EATING);
}
public static void showStatus(PersonStatus status){
switch(status){
case SLEEP :System.out.println("正在睡觉");break;
case WORKING:System.out.println("曾在工作");break;
case EATING:System.out.println("正在吃饭");break;
default:System.out.println("正在忙于其他事情");
}
//输出结果是正在吃饭
}
注意:switch()只能用五种类型Char,byte,short,int,enum
1.3枚举的本质
定义枚举类型时本质上就是定义一个类别,只不过很多细节由编译器帮您完成了,所以在某些程度上,enum关键字的作用就像是class或interface。
当使用”enum”定义 枚举类型时,实质上定义出来的类型继承自java.lang.Enum类型,而每个枚举的成员其实就是您定义的枚举的一个实例,它们都是 public final static 类型的,所以你无法改变它们,可以直接使用。
JAVASE API 说明
Enum<E extends Enum<E>>是所有枚举类型的基类
说明了所有的enum类型的超类都是 java.lang.Enum
那么既然是一个类,那么就可以有成员以及构造方法。
下面新的PersonStatus枚举:
public enum PersonStatus {
SLEEP("睡觉"),WORKING("工作"),EATING("吃饭");
String value;
PersonStatus(String value){
this.value=value;
}
public String getValue(){
return this.value;
}
}
应用
public static void main(String[] args) {
System.out.println(PersonStatus.SLEEP.getValue());//睡觉
}
可以看出比上面要简洁的多。
1.4枚举类型之间的比较
枚举类型的比较方法:compareTo(E o)
源码:
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的变量的值
Ordinal值的解释:
/**
* The ordinal of this enumeration constant (its position
* in the enum declaration, where the initial constant is assigned
* an ordinal of zero).
*
* Most programmers will have no use for this field. It is designed
* for use by sophisticated enum-based data structures, such as
* {@link java.util.EnumSet} and {@link java.util.EnumMap}.
*/
private final int ordinal;
意思是它是在枚举类型中声明的位置,第一个位置是0,以此类推。
一般用不到这个变量,只有在复杂的枚举结构类型中采用的到比较EnumSet,EnumMap(这两种类型在后面会讲到)。
Ordinal的demo:
public static void main(String[] args) {
// 下面是for的增强循环方法,遍历枚举的所有值
for (ColorType color : ColorType.values()) {
System.out.println(color + "的位置是 " + color.ordinal());
// RED的位置是 0
// BLACK的位置是 1
// YELLOW的位置是 2
}
}
枚举比较的demo:
public static void main(String[] args) {
compareToPersonStatus(PersonStatus.SLEEP);
}
public static void compareToPersonStatus(PersonStatus status){
for(PersonStatus stat : PersonStatus.values()){
System.out.println(status.compareTo(stat));
// 0
// -1
// -2
}
}
二.枚举集合类型
2.1EnumSet
EnumSet的名称说明了其作用,它是J2SE 5.0后加入的新类别,可以协助建立枚举值的集合,它提供了一系列的静态方法,可以指定不同的集合的建立方式。
EnumSet的基本应用:
遍历枚举集合类型
public static void main(String[] args) {
EnumSet<PersonStatus> set = EnumSet.of(PersonStatus.EATING,
PersonStatus.SLEEP);
// 遍历enumSet
interratorPersonStatus(set);
}
public static void interratorPersonStatus(EnumSet<PersonStatus> set){
for (Iterator<PersonStatus> it = set.iterator(); it.hasNext();) {
PersonStatus tmp = it.next();
System.out.println(tmp.getValue());
// 吃饭
// 睡觉
}
}
上述用到的of方法,源码如下:
/** Creates an enum set initially containing the specified elements.
* Overloadings of this method exist to initialize an enum set with
* one through five elements. A sixth overloading is provided that
* uses the varargs feature. This overloading may be used to create
* an enum set initially containing an arbitrary number of elements, but
* is likely to run slower than the overloadings that do not use varargs.
* @param e1 an element that this set is to contain initially
* @param e2 another element that this set is to contain initially
* @throws NullPointerException if any parameters are null
* @return an enum set initially containing the specified elements
*/
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
EnumSet<E> result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
return result;
}
意思是创建一个set集合,并利用 e1 e2初始化。
上述方法利用到的noneOf源码:
/**
* Creates an empty enum set with the specified element type.
* @throws NullPointerException if <tt>elementType</tt> is null
*/
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
意思是创建一个指定类型的EnumSet集合,参数是class类型
noneOf Demo:
public static void noneOfPersonStatus(){
EnumSet<PersonStatus> set=EnumSet.noneOf(PersonStatus.class);
set.add(PersonStatus.WORKING);
set.add(PersonStatus.SLEEP);
set.add(PersonStatus.EATING);
interratorPersonStatus(set);
//吃饭
// 工作
// 睡觉
}
利用noneOf的方法构造了Enumset,然后调用add方法添加枚举类型。
2.2 EnumMap
EnumMap的定义:EnumMap<K extends Enum<K>,V>
可以看出枚举映射中所有的键都必须来自单个枚举类型,该枚举类型在创建映射时显示或隐式的指定,枚举映射在内部表示为数组。
构造方法:
- EnumMap(Class <K> keyType)
- EnumMap(EnumMap<K,? extends V> m)
- EnumMap(Map<K,? extends V> m)
简单的应用demo:
public static void main(String[] args) {
EnumMap<ColorType,String> map=new EnumMap<ColorType,String>(ColorType.class);
map.put(ColorType.BLACK, "黑色");
map.put(ColorType.RED,"红色");
System.out.println(map.get(ColorType.RED));//红色
}
2567

被折叠的 条评论
为什么被折叠?



