Java中:关键字enum可以将一组具名的值得有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用。这是一种非常有用的功能。
基本enum特性
//定义一组枚举值
enum Shrubbery {GROUND,CRAWLING,HANDING}
public class EnumClass {
public static void main(String[] args) {
//遍历所有值
for (Shrubbery s : Shrubbery.values()){
//打印每个值的排序号
System.out.println(s + " odinal: " + s.ordinal());
System.out.println(s.compareTo(Shrubbery.CRAWLING) + " ");
//判断相等
System.out.println(s.equals(Shrubbery.CRAWLING));
//使用==比较
System.out.println(s == Shrubbery.CRAWLING);
//获得枚举值的定义类
System.out.println(s.getDeclaringClass());
//名字
System.out.println(s.name());
System.out.println("----------------------------------");
}
}
}
输出:
GROUND odinal: 0
-1
false
false
class com.javass.enums.Shrubbery
GROUND
----------------------------------
CRAWLING odinal: 1
0
true
true
class com.javass.enums.Shrubbery
CRAWLING
----------------------------------
HANDING odinal: 2
1
false
false
class com.javass.enums.Shrubbery
HANDING
----------------------------------
ordinal()方法返回enum实例声明时次序,从0开始;
enum 实例可以使用==来比较,系统自动提供equals和hashcode方法;
getDeclaringClass,返回其enum类;
name返回声明时的名字。
向enum中添加新方法
enum除了不能被继承之外,可以看做一个普通的类。可以添加新的方法。
public enum OzWitch {
WEST("desc of west"),
NORTH("desc of north"),
EAST("desc of east"),
SOUTH("desc of south"); //必须使用;结束enum实例声明,才能添加方法,否则会报错
//自定义属性
private String desc;
//私有构造函数
private OzWitch(String desc){
this.desc = desc;
}
public String getDesc(){
return this.desc;
}
public static void main(String[] args){
for(OzWitch s : OzWitch.values()){
System.out.println(s.getDesc());
}
}
}
构造器也可以不用私有化,这样也不会造成访问权限的变化。因为enum在实例声明结束之后,就不允许再调用构造函数来创建实例。
switch 中使用enum
enum Signal {
GREEN, YELLOW, RED
};
public class TrafficLight {
Signal color = Signal.RED;
public void change(){
switch(color){
//case 中不必使用enum类型名来修饰 实例
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
public static void main(String[] args) {
TrafficLight tl = new TrafficLight();
for(int i=0;i<7;i++){
System.out.println(tl.color.name());
tl.change();
}
}
}
enum实现其他接口
所有的枚举都继承与Java.lang.Enum类。所以自己的枚举不能继承其他类,只能实现接口。
//枚举enum 实现一个接口
enum CartoonCharacter implements Generator<CartoonCharacter> {
SLAPPY, SPANKY, PUNCHY, SILLY, BOUNCY, NUTTY, BOB;
private Random rand = new Random(47);
@Override
public CartoonCharacter next() {
return values()[rand.nextInt(values().length)];
}
}
public class EnumImplementation {
//接受Generator<T> 接口作为参数的方法
public static <T> void printNext(Generator<T> rg) {
System.out.println(rg.next() + ", ");
}
public static void main(String[] args) {
CartoonCharacter cc = CartoonCharacter.BOB;
for (int i = 0; i < 10; i++) {
//所有/接受Generator<T> 接口作为参数的方法,都可以使用 CartoonCharacter枚举实例
printNext(cc);
}
}
}
所有接受Generator<T> 接口作为参数的方法,都可以使用 CartoonCharacter枚举实例
EunmSet的使用
EnumSet是专为枚举类型设计的集合,弥补了Enum不可以增删元素的缺陷。
enum AlarmPoints {
STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, BATHROOM, UTILITY, KITCHEN
}
public class EnumSets {
public static void main(String[] args) {
//创建一个空的enumset
EnumSet<AlarmPoints> points = EnumSet.noneOf(AlarmPoints.class);
//添加一个数据
points.add(AlarmPoints.BATHROOM);
System.out.println(points);
//添加一組数据
points.addAll(EnumSet.of(AlarmPoints.STAIR1, AlarmPoints.STAIR2,AlarmPoints.KITCHEN));
System.out.println(points);
//创建一个包含枚举的所有实例的set
points = EnumSet.allOf(AlarmPoints.class);
System.out.println(points);
//删除数据
points.removeAll(EnumSet.of(AlarmPoints.STAIR1, AlarmPoints.STAIR2,AlarmPoints.KITCHEN));
System.out.println(points);
//删除数据(范围)
points.removeAll(EnumSet.range(AlarmPoints.OFFICE1, AlarmPoints.OFFICE4));
System.out.println(points);
//创建一个包含枚举的所有实例的set
points = EnumSet.complementOf(points);
System.out.println(points);
}
}
使用EnumMap
EnumMap是一中特殊的Map,它的Key必须是一个enum的实例。enum不能增删元素,所EnumMap内部使用数组实现,所以速度很快。
interface Command{
void action();
}
public class EnumMaps {
public static void main(String[] args) {
//初始化,必须指定枚举类型
EnumMap<AlarmPoints,Command> em = new EnumMap<AlarmPoints,Command>(AlarmPoints.class);
//map put 元素
em.put(AlarmPoints.KITCHEN, new Command(){
@Override
public void action() {
System.out.println(" Kitch fire");
}
});
em.put(AlarmPoints.BATHROOM, new Command(){
public void action(){
System.out.println(" bathroom alert");
}
});
//遍历 执行command
for(Map.Entry<AlarmPoints, Command> e : em.entrySet() ){
e.getValue().action();
}
//没有put的元素,会返回null
try{
Command c = em.get(AlarmPoints.LOBBY);
c.action();
}catch(Exception e){
e.printStackTrace();
}
}
}