目录

一、枚举的相关概念

二、Enum

(一)相关方法

(二)特性

三、EnumSet

相关方法

四、EnumMap

五、枚举的常见用法

(一)常量

(二)switch

(三)向枚举中添加新方法

(四)覆盖枚举的方法

(五)实现接口

(六)使用接口组织枚举

六、代码


Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。

Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割。

本章节将对枚举进行详细阐述。

java 根据枚举字段获取具体枚举 java枚举实现数据字典_System

一、枚举的相关概念

1、定义:枚举是一个特殊的类,一般表示一组常量,例如一年四季,一年的十二个月以及一周七天等。Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割。

2、示例:

(1)定义一个颜色的枚举类

// 定义一个颜色的枚举类
enum Color{
    Red, Green, Blue;
}

(2)引用

public static void main(String[] args){
    Color c = Color.Red;
}

3、优点:将常量组织起来,统一进行管理

4、场景:错误码、状态机等

5、本质:java.lang.Enum的子类

二、Enum

(一)相关方法

enum定义的枚举类默认继承了java.lang.Enum类,并实现了java.lang.Serializable和java.lang.Comparable接口。

其种,以下方法位于java.lang.Enum类中,简单介绍以下方法的使用。

  • values():返回枚举类中所有的值
  • valueOf():返回指定字符串值的枚举常量
  • name():返回实例名
  • ordinal():查找枚举常量的索引
  • equals():判断是否是同一对象,也可使用==比较
  • getDeclaringClass():返回实例所属的enum类型

代码实例

public class Day23 {
    // 定义一个颜色的枚举类
    enum Color{
        Red, Green, Blue;
    }

    // 定义一个一年四季的枚举类
    enum Season{
        Spring, Summer, Autumn, Winter;
    }

    public static void main(String[] args){
        Color r = Color.Red;
        Color g = Color.Green;
        Color b = Color.Blue;

        Season sp = Season.Spring;
        Season su = Season.Summer;
        Season au = Season.Autumn;
        Season wi = Season.Winter;

        /* 方法 */
        // values(): 返回枚举类中所有的值
        System.out.println("------values()------");
        for (Color color: Color.values()) {
            System.out.println(color);
        }

        // valueOf(): 返回指定字符串值的枚举常量
        System.out.println("------valueOf()------");
        System.out.println(Color.valueOf("Red"));
        System.out.println(Color.valueOf("Green"));
        System.out.println(Color.valueOf("Blue"));

        // name(): 返回实例名
        System.out.println("------name()------");
        System.out.println(r.name());
        System.out.println(g.name());
        System.out.println(b.name());

        // ordinal(): 查找枚举常量的索引
        System.out.println("------ordinal()------");
        System.out.println(r.ordinal());
        System.out.println(g.ordinal());
        System.out.println(b.ordinal());

        // equals(): 判断是否是同一对象,也可使用==比较
        System.out.println("------equals()------");
        System.out.println(r.equals(g)); // false
        System.out.println(r.equals(r)); // true
        System.out.println(r.equals(sp)); // false

        // getDeclaringClass(): 返回实例所属的enum类型
        System.out.println("------getDeclaringClass()------");
        System.out.println(r.getDeclaringClass());
        System.out.println(sp.getDeclaringClass());
    }
}

结果 

------values()------
Red
Green
Blue
------valueOf()------
Red
Green
Blue
------name()------
Red
Green
Blue
------ordinal()------
0
1
2
------equals()------
false
true
false
------getDeclaringClass()------
class Java_learning.Day23$Color
class Java_learning.Day23$Season

(二)特性

  1. 枚举不能继承,但可以看做一个常规的类;
  2. 不允许使用“=”为枚举常量赋值,可使用方法显示赋值;
  3. enum可以添加普通方法、静态方法、抽象方法、构造方法;
  4. enum可以实现接口,但无法继承,因为enum继承java.lang.Enum类,Java不允许多继承,所以 enum无法继承其他类。

三、EnumSet

EnumSet是枚举类型的高性能Set实现,它要求放入它的枚举常量必须属于同一枚举类型。

相关方法

  • noneOf():创建空集合
  • allOf():创建包含所有元素的结合
  • of():创建包含指定元素的集合
  • range():创建范围集合
  • complementOf():补集
  • copyOf():复制集合

代码实例

// 创建空集合_EnumSet.noneOf(Month.class)
EnumSet<Month> enumSet1 =  EnumSet.noneOf(Month.class);

// 创建包含所有元素的集合_EnumSet.allOf(Month.class)
EnumSet<Month> enumSet2 =  EnumSet.allOf(Month.class);

// 创建包含指定元素的集合_EnumSet.of(Month.JANUARY, Month.DECEMBER)
EnumSet<Month> enumSet3 =  EnumSet.of(Month.JANUARY, Month.DECEMBER);

// 创建范围集合_EnumSet.range(Month.JANUARY, Month.OCTOBER)
// 第一个枚举值的索引位置必须大于第二个枚举值,不然会导致异常。
EnumSet<Month> enumSet4 = EnumSet.range(Month.JANUARY, Month.OCTOBER);

// 补集_EnumSet.complementOf(enumSet4)
EnumSet<Month> enumSet5 = EnumSet.complementOf(enumSet4);

// 复制集合
EnumSet<Month> enumSet6 = EnumSet.copyOf(enumSet5);

System.out.println("noneOf:       " + enumSet1);
System.out.println("allOf:        " + enumSet2);
System.out.println("of:           " + enumSet3);
System.out.println("range:        " + enumSet4);
System.out.println("complementOf: " + enumSet5);
System.out.println("copyOf:       " + enumSet6);

结果

noneOf:       []
allOf:        [JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER]
of:           [JANUARY, DECEMBER]
range:        [JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER]
complementOf: [NOVEMBER, DECEMBER]
copyOf:       [NOVEMBER, DECEMBER]

四、EnumMap

EnumMap是专门为枚举类型定制的Map,EnumMap 在使用上跟HashMap差不多,但是EnumMap 的性能更好,所以,如果键为Enum 类型时,建议使用 EnumMap 代替 HashMap。

代码实例

EnumMap<DayOfWeek, Integer> dayMap = new EnumMap<>(DayOfWeek.class);
for (DayOfWeek value: DayOfWeek.values()){
    dayMap.put(value, value.ordinal());
}

dayMap.forEach((k, v) -> System.out.println(k + " -> " + v));

结果

MONDAY -> 0
TUESDAY -> 1
WEDNESDAY -> 2
THURSDAY -> 3
FRIDAY -> 4
SATURDAY -> 5
SUNDAY -> 6

五、枚举的常见用法

(一)常量

创建四个方向的枚举常量:

enum Direction{
    up, down, left, right;
}

(二)switch

在 switch 中使用枚举类

// 常量
enum Direction{
    up, down, left, right;
}

// switch
static class Reverse{
    Direction d = Direction.right;

    public void change(){
        switch (d){
            case up:
                d = Direction.down;
                break;
            case down:
                d = Direction.up;
                break;
            case left:
                d = Direction.right;
                break;
            case right:
                d = Direction.left;
                break;
        }
    }
}

(三)向枚举中添加新方法

enum Signal{
    RED("红色", 1), GREEN("绿色", 2), YELLOW("黄色", 3);

    // 成员变量
    private String name;
    private int index;

    // 构造方法
    Signal(String name, int index) {
        this.name = name;
        this.index = index;
    }

    // 普通方法
    public String getName(int index){
        for (Signal s: Signal.values()){
            if (s.getIndex() == index){
                return s.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;
    }
}

(四)覆盖枚举的方法

enum Family{
    Father("父亲", 1), Mother("母亲", 1), Brother("兄弟", 1), Sister("姐妹", 1);
    private String name;
    private int index;

    Family(String name, int index) {
        this.name = name;
        this.index = index;
    }

    // 覆盖方法
    public String toString(){
        return this.index+"_"+this.name;
    }
}

(五)实现接口

interface Move{
    void move_up();
    void move_down();
    void move_left();
    void move_right();
}

enum interfaceMove implements Move{
    up("上", 1), down("下", 2), left("左", 3), right("右", 4);
    
    private String dir;
    private int index;
    
    interfaceMove(String dir, int index) {
        this.dir = dir;
        this.index = index;
    }

    @Override
    public void move_up() {
        
    }

    @Override
    public void move_down() {

    }

    @Override
    public void move_left() {

    }

    @Override
    public void move_right() {

    }
}

(六)使用接口组织枚举

interface Animal{
    enum Dog implements Animal{
        dog1, dog2, dog3;
    }

    enum Cat implements Animal{
        cat1, cat2, cat3;
    }
}

六、代码

import org.threeten.bp.DayOfWeek;
import org.threeten.bp.Month;

import java.util.EnumMap;
import java.util.EnumSet;

public class Day23 {
    // 定义一个颜色的枚举类
    enum Color{
        Red, Green, Blue;
    }

    // 定义一个一年四季的枚举类
    enum Season{
        Spring, Summer, Autumn, Winter;
    }

    /* 常见用法 */
    // 常量
    enum Direction{
        up, down, left, right;
    }

    // switch
    static class Reverse{
        Direction d = Direction.right;

        public void change(){
            switch (d){
                case up:
                    d = Direction.down;
                    break;
                case down:
                    d = Direction.up;
                    break;
                case left:
                    d = Direction.right;
                    break;
                case right:
                    d = Direction.left;
                    break;
            }
        }
    }

    // 向枚举中添加新方法
    enum Signal{
        RED("红色", 1), GREEN("绿色", 2), YELLOW("黄色", 3);

        // 成员变量
        private String name;
        private int index;

        // 构造方法
        Signal(String name, int index) {
            this.name = name;
            this.index = index;
        }

        // 普通方法
        public String getName(int index){
            for (Signal s: Signal.values()){
                if (s.getIndex() == index){
                    return s.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;
        }
    }

    // 覆盖枚举的方法
    enum Family{
        Father("父亲", 1), Mother("母亲", 1), Brother("兄弟", 1), Sister("姐妹", 1);
        private String name;
        private int index;

        Family(String name, int index) {
            this.name = name;
            this.index = index;
        }

        // 覆盖方法
        public String toString(){
            return this.index+"_"+this.name;
        }
    }

    // 实现接口
    interface Move{
        void move_up();
        void move_down();
        void move_left();
        void move_right();
    }

    enum interfaceMove implements Move{
        up("上", 1), down("下", 2), left("左", 3), right("右", 4);

        private String dir;
        private int index;

        interfaceMove(String dir, int index) {
            this.dir = dir;
            this.index = index;
        }

        @Override
        public void move_up() {

        }

        @Override
        public void move_down() {

        }

        @Override
        public void move_left() {

        }

        @Override
        public void move_right() {

        }
    }

    // 使用接口组织枚举
    interface Animal{
        enum Dog implements Animal{
            dog1, dog2, dog3;
        }

        enum Cat implements Animal{
            cat1, cat2, cat3;
        }
    }

    public static void main(String[] args){
        Color r = Color.Red;
        Color g = Color.Green;
        Color b = Color.Blue;

        Season sp = Season.Spring;
        Season su = Season.Summer;
        Season au = Season.Autumn;
        Season wi = Season.Winter;

        /* 方法 */
        // values(): 返回枚举类中所有的值
        System.out.println("------values()------");
        for (Color color: Color.values()) {
            System.out.println(color);
        }

        // valueOf(): 返回指定字符串值的枚举常量
        System.out.println("------valueOf()------");
        System.out.println(Color.valueOf("Red"));
        System.out.println(Color.valueOf("Green"));
        System.out.println(Color.valueOf("Blue"));

        // name(): 返回实例名
        System.out.println("------name()------");
        System.out.println(r.name());
        System.out.println(g.name());
        System.out.println(b.name());

        // ordinal(): 查找枚举常量的索引
        System.out.println("------ordinal()------");
        System.out.println(r.ordinal());
        System.out.println(g.ordinal());
        System.out.println(b.ordinal());

        // equals(): 判断是否是同一对象,也可使用==比较
        System.out.println("------equals()------");
        System.out.println(r.equals(g)); // false
        System.out.println(r.equals(r)); // true
        System.out.println(r.equals(sp)); // false

        // getDeclaringClass(): 返回实例所属的enum类型
        System.out.println("------getDeclaringClass()------");
        System.out.println(r.getDeclaringClass());
        System.out.println(sp.getDeclaringClass());

        /* 工具类——EnumSet */
        // 创建空集合_EnumSet.noneOf(Month.class)
        EnumSet<Month> enumSet1 =  EnumSet.noneOf(Month.class);

        // 创建包含所有元素的集合_EnumSet.allOf(Month.class)
        EnumSet<Month> enumSet2 =  EnumSet.allOf(Month.class);

        // 创建包含指定元素的集合_EnumSet.of(Month.JANUARY, Month.DECEMBER)
        EnumSet<Month> enumSet3 =  EnumSet.of(Month.JANUARY, Month.DECEMBER);

        // 创建范围集合_EnumSet.range(Month.JANUARY, Month.OCTOBER)
        // 第一个枚举值的索引位置必须大于第二个枚举值,不然会导致异常。
        EnumSet<Month> enumSet4 = EnumSet.range(Month.JANUARY, Month.OCTOBER);

        // 补集_EnumSet.complementOf(enumSet4)
        EnumSet<Month> enumSet5 = EnumSet.complementOf(enumSet4);

        // 复制集合
        EnumSet<Month> enumSet6 = EnumSet.copyOf(enumSet5);

        System.out.println("noneOf:       " + enumSet1);
        System.out.println("allOf:        " + enumSet2);
        System.out.println("of:           " + enumSet3);
        System.out.println("range:        " + enumSet4);
        System.out.println("complementOf: " + enumSet5);
        System.out.println("copyOf:       " + enumSet6);

        /* 工具类——EnumMap */
        System.out.println("------EnumMap------" + enumSet6);

        EnumMap<DayOfWeek, Integer> dayMap = new EnumMap<>(DayOfWeek.class);
        for (DayOfWeek value: DayOfWeek.values()){
            dayMap.put(value, value.ordinal());
        }

        dayMap.forEach((k, v) -> System.out.println(k + " -> " + v));
}
}