枚举类型
public enum Spiciness {
/**
* 具名值,枚举类型的实例,常量
* 按照常量书写的惯例它们都用大写字母表示
*/
NOT, MID, MEDIUM, HOT, FLAMING
}
import org.testng.annotations.Test;
public class SpicinessTest {
/**
* 在你创建enum时,编译器会自动添加一些有用的特性
*
*/
@Test(enabled = false)
public void testSimpleEnumUse() {
Spiciness howHot = Spiciness.MEDIUM;
// 输出MEDIUM。 编译器自动添加toString方法,显示enum实例的名字
System.out.print(howHot);
}
/**
* 尽管enum看起来像是一种新的数据类型,但是这个关键字知识为enum生成对应的类时,产生某些编译行为
*/
@Test(enabled = true)
public void testEnumOrder() {
// static values()方法,是由编译器添加的static方法,Enum类中并没有values方法,按照enum常量的声明顺序,产生这些常量值构成的数组
for(Spiciness s : Spiciness.values()) {
// ordinal()方法,用来表示某个特定enum常量的声明顺序
System.out.println(s + ", ordinal " + s.ordinal());
}
}
}
基本enum特性
public enum Shrubbery {
/**
* 创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum
*/
GROUND, CRAWLING, HANGING
}
import org.testng.annotations.Test;
public class ShrubberyTest {
@Test(enabled = true)
public void testShrubbery() {
for(Shrubbery s : Shrubbery.values()) {
// ordinal()方法返回一个int值,这是每个enum实例在声明时的次序,从0开始
System.out.println(s + " ordinal: " + s.ordinal());
System.out.println(s.compareTo(Shrubbery.CRAWLING) + " ");
System.out.println(s.equals(Shrubbery.CRAWLING) + " ");
System.out.println(s == Shrubbery.CRAWLING);
// 在enum实例上调用getDeclaringClass()方法,我们就能知道其所属的enum类
System.out.println(s.getDeclaringClass());
// name()方法返回enum实例声明时的名字,这与使用toString()方法效果相同
System.out.println(s.name());
System.out.println("----------------------");
}
for(String s : "HANGING CRAWLING GROUND".split(" ")) {
/**
* valueOf()方法根据给定的名字返回相应的enum实例,如果不存在给定名字的实例,将会抛出异常
* s == null, throw new NullPointerException
* s not exist throw new IllegalArgumentException
*/
Shrubbery shrubbery = Enum.valueOf(Shrubbery.class, s);
System.out.println(shrubbery);
}
}
}
向enum中添加新方法
public enum OzWitch {
/** 如果你打算定义自己的方法,那么必须在enum实例序列的最后添加一个分号
* Java要求你必须先定义enum实例,如果在定义enum实例之前定义了任何方法或属性,那么编译时就会得到错误信息
*/
WEST("Miss Gulch, aka the Wicked Witch of the West"),
NORTH("Glinda, the Good Witch of the North"),
EAST("Wicked Witch of the East, wearer of the Ruby " + "Slippers, crushed by Dorothy's house"),
SOUTH("Good by inference, but missing");
private String description;
OzWitch(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
import org.testng.annotations.Test;
public class OzWitchTest {
@Test
public void test() {
for(OzWitch witch : OzWitch.values()) {
System.out.println(witch + ": " + witch.getDescription());
}
}
}
覆盖enum中的方法
public enum SpaceShip {
SCOUT, CARGO, TRANSPORT, CRUISER, BATTLESHIP, MOTHERSHIP;
/**
* 覆盖enum的toString()方法
* @return
*/
public String toString() {
String id = name();
String lower = id.substring(1).toLowerCase();
return id.charAt(0) + lower;
}
}
import org.testng.annotations.Test;
public class SpaceShipTest {
@Test
public void test() {
for(SpaceShip s : SpaceShip.values()) {
System.out.println(s);
}
}
}
switch
public class Burrito {
Spiciness degree;
public Burrito(Spiciness degree) {
this.degree = degree;
}
/**
* enum有一个特别实用的特性,即它可以在switch语句内使用
*/
public void describe() {
System.out.print("This burrito is ");
switch (degree) {
case NOT:
System.out.println("not spicy at all.");
break;
case MID:
case MEDIUM:
System.out.println("a little hot.");
break;
case HOT:
case FLAMING:
default:
System.out.println("maybe too hot.");
}
}
}
import org.testng.annotations.Test;
public class BurritoTest {
@Test(enabled = true)
public void testDescribe() {
Burrito
plain = new Burrito(Spiciness.NOT),
greenChile = new Burrito(Spiciness.MEDIUM),
jalapeno = new Burrito(Spiciness.HOT);
plain.describe();
greenChile.describe();
jalapeno.describe();
}
}
EnumSet
public enum AlarmPoints {
STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3,
OFFICE4, BATHROOM, UTILITY, KITCHEN
}
import org.testng.annotations.Test;
import java.util.EnumSet;
/**
* 使用static import 简化enum常量的使用
*/
import static com.dmw.enumerated.AlarmPoints.*;
public class EnumSetTest {
@Test
public void test() {
// Empty set,EnumSet中的元素必须来自一个enum
EnumSet points = EnumSet.noneOf(AlarmPoints.class);
points.add(BATHROOM);
System.out.println(points);
points.addAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));
System.out.println(points);
points = EnumSet.allOf(AlarmPoints.class);
System.out.println(points);
points.removeAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));
System.out.println(points);
points.removeAll(EnumSet.range(OFFICE1, OFFICE4));
System.out.println(points);
points = EnumSet.complementOf(points);
System.out.println(points);
}
}
EnumMaps
import java.util.EnumMap;
import java.util.Map;
import static com.dmw.enumerated.AlarmPoints.*;
public class EnumMaps {
public static void main(String[] args) {
EnumMap em = new EnumMap<>(AlarmPoints.class);
em.put(KITCHEN, new Command() {
@Override
public void action() {
System.out.println("Kitchen fire");
}
});
em.put(BATHROOM, new Command() {
@Override
public void action() {
System.out.println("Bathroom alert!");
}
});
for(Map.Entry e : em.entrySet()) {
System.out.println(e.getKey() + ":");
e.getValue().action();
}
try {
em.get(UTILITY).action();
} catch (Exception e) {
System.out.println(e);
}
}
}
interface Command {
void action();
}
常量相关方法
import java.text.DateFormat;
import java.util.Date;
/**
* 1. Java的enum有一个非常有趣的特性,即它允许程序员为enum实例编写方法,从而为每个enum实例赋予各自不同的行为
* 2. 通过相应的enum实例,我们可以调用对应的方法。这通常也称为表驱动的代码(table-driven code, 和命令模式有一定的相似之处)
* 3. 每个enum元素(例如DATE_TIME)都是一个ConstantSpecificMethod的static final实例
*/
public enum ConstantSpecificMethod {
DATE_TIME {
@Override
String getInfo() {
return DateFormat.getDateInstance().format(new Date());
}
},
CLASSPATH {
@Override
String getInfo() {
return System.getenv("CLASSPATH");
}
},
VERSION {
@Override
String getInfo() {
return System.getProperty("java.version");
}
};
abstract String getInfo();
}
import org.testng.annotations.Test;
public class ConstantSpecificMethodTest {
@Test
public void test() {
for(ConstantSpecificMethod csm : ConstantSpecificMethod.values()) {
System.out.println(csm.getInfo());
}
}
}
比匿名内部类更加简洁高效
import java.util.EnumSet;
/**
* 与使用匿名内部类相比较,定义常量相关方法的语法更高效、简洁
*/
public class CarWash {
public enum Cycle {
UNDERBODY {
@Override
void action() {
System.out.println("Spraying the underbody");
}
},
WHEELWASH {
@Override
void action() {
System.out.println("Washing the wheels");
}
},
PREWASH {
@Override
void action() {
System.out.println("Loosening the dirt");
}
},
BASIC {
@Override
void action() {
System.out.println("The basic wash");
}
},
HOTWAX {
@Override
void action() {
System.out.println("Applying hot wax");
}
},
RINSE {
@Override
void action() {
System.out.println("Rinsing");
}
},
BLOWDRY {
@Override
void action() {
System.out.println("Blowing dry");
}
};
abstract void action();
}
EnumSet cycles = EnumSet.of(Cycle.BASIC, Cycle.RINSE);
public void add(Cycle cycle) {
cycles.add(cycle);
}
public void washCar() {
for(Cycle c : cycles) {
c.action();
}
}
@Override
public String toString() {
return cycles.toString();
}
public static void main(String[] args) {
CarWash wash = new CarWash();
System.out.println(wash);
wash.washCar();
// Order of addition is unimportant
wash.add(Cycle.BLOWDRY);
// Duplicates ignored
wash.add(Cycle.BLOWDRY);
wash.add(Cycle.RINSE);
wash.add(Cycle.HOTWAX);
System.out.println(wash);
wash.washCar();
}
}