一、认识枚举
JDK1.5引入了新的类型——枚举。在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便。
二、枚举用法
(1)用法1:常量
在JDK1.5 之前,我们定义常量都是: public static fianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
public enum Color {
RED, GREEN, BLANK, YELLOW;
}
(2)用法2:switch
JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
enum Signal {
GREEN, YELLOW, RED;
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
详细升级版本:
/**
* 季节枚举(不带参数的枚举常量)这个是最简单的枚举使用实例
* Ordinal 属性,对应的就是排列顺序,从0开始。 (按照枚举的顺序以此递增)
*/
private enum SimpleEnum {
SPRING, // ordinal 0
SUMMER, // ordinal 1
AUTUMN, // ordinal 2
WINTER; // ordinal 3
}
private static void testSwitchCase() {
String typeName = "f5";
//这几行注释呢,你可以试着三选一,测试一下效果。
//String typeName = "firewall";
//String typeName = "secretMac";
TypeEnum typeEnum = TypeEnum.fromTypeName(typeName);
if (typeEnum == null) {
return;
}
switch (typeEnum) {
case FIREWALL: // case 中我们可以使用下面三种枚举的属性用来做 switch-case 的具体情况。
System.out.println("枚举名称(即默认自带的属性 name 的值)是:" + typeEnum.name());
System.out.println("排序值(默认自带的属性 ordinal 的值)是:" + typeEnum.ordinal());
System.out.println("枚举的自定义属性 typeName 的值是:" + typeEnum.getTypeName());
break;
case SECRET:
System.out.println("枚举名称(即默认自带的属性 name 的值)是:" + typeEnum.name());
System.out.println("排序值(默认自带的属性 ordinal 的值)是:" + typeEnum.ordinal());
System.out.println("枚举的自定义属性 typeName 的值是:" + typeEnum.getTypeName());
break;
case BALANCE:
System.out.println("枚举名称(即默认自带的属性 name 的值)是:" + typeEnum.name());
System.out.println("排序值(默认自带的属性 ordinal 的值)是:" + typeEnum.ordinal());
System.out.println("枚举的自定义属性 typeName 的值是:" + typeEnum.getTypeName());
break;
default:
System.out.println("default");
}
}
(3)用法3:向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。
- 获取所有的name;
- 获取所有的index;
- 重写 toString() 方法;
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
// 覆盖方法
@Override
public String toString() {
return this.index + "_" + this.name;
}
// 测试:覆盖方法
public static void main(String[] args) throws Exception {
System.out.println(Color.BLANK.toString()); // 3_白色
}
}
(4)用法4:实现接口
所有的枚举都继承自 java.lang.Enum 类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。
public interface Behaviour {
void print();
String getInfo();
}
public enum Color implements Behaviour {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//接口方法
@Override
public String getInfo() {
return this.name;
}
//接口方法
@Override
public void print() {
System.out.println(this.index + ":" + this.name);
}
}
(5)用法5:使用接口组织枚举
public interface Food {
enum Coffee implements Food{ // 咖啡
BLACK_COFFEE, DECAF_COFFEE, LATTE, CAPPUCCINO;
}
enum Dessert implements Food{ // 甜点
FRUIT, CAKE, GELATO;
}
}
/**
* 测试继承接口的枚举的使用
*/
private static void testImplementsInterface() {
for (Food.DessertEnum dessertEnum : Food.DessertEnum.values()) {
System.out.print(dessertEnum + " ");
}
System.out.println();
//我这地方这么写,是因为我在自己测试的时候,把这个coffee单独到一个文件去实现那个food接口,而不是在那个接口的内部。
for (CoffeeEnum coffee : CoffeeEnum.values()) {
System.out.print(coffee + " ");
}
System.out.println();
//搞个实现接口,来组织枚举,简单讲,就是分类吧。如果大量使用枚举的话,这么干,在写代码的时候,就很方便调用啦。
//还有就是个“多态”的功能吧,
Food food = Food.DessertEnum.CAKE;
System.out.println(food);
food = CoffeeEnum.BLACK_COFFEE;
System.out.println(food);
}
(6)方法6:枚举集合
public class Test {
enum WeekDayEnum {
MON, TUE, WED, THU, FRI, SAT, SUN;
}
public static void main(String[] args) {
EnumSet<WeekDayEnum> week = EnumSet.noneOf(WeekDayEnum.class);
week.add(WeekDayEnum.MON);
System.out.println("EnumSet中的元素(查看枚举集合的所有元素):" + week);
week.remove(WeekDayEnum.MON);
System.out.println("EnumSet中的元素(清空指定枚举元素):" + week);
week.addAll(EnumSet.complementOf(week));
System.out.println("EnumSet中的元素(所有元素):" + week);
// 范围清空的原理? 是枚举中默认的ordinal自动给每个枚举定编号了。所以可以使用范围查询和移除操作
week.removeAll(EnumSet.range(WeekDayEnum.FRI, WeekDayEnum.SAT));
System.out.println("EnumSet中的元素(去除周五到周六):" + week);
}
}
测试结果: