Java 枚举enum

概念

enum 的全称为 enumeration, 是 JDK 1.5 中引入的新特性。

在Java中,被 enum 关键字修饰的类型就是枚举类型。形式如下:

enum Color { RED, GREEN, BLUE }

如果枚举不添加任何方法,枚举值默认为从0开始的有序数值。以 Color 枚举类型举例,它的枚举常量依次为 RED:0,GREEN:1,BLUE:2

枚举的好处:可以将常量组织起来,统一进行管理。

枚举的典型应用场景:错误码、状态机等。

枚举类型的本质

尽管 enum 看起来像是一种新的数据类型,事实上,enum是一种受限制的类,并且具有自己的方法。创建enum时,编译器会为你生成一个相关的类,这个类继承自 java.lang.Enum

枚举的方法

在enum中,提供了一些基本方法:

  • values():返回 enum 实例的数组,而且该数组中的元素严格保持在 enum 中声明时的顺序。
  • name():返回实例名。
  • ordinal():返回实例声明时的次序,从0开始。
  • getDeclaringClass():返回实例所属的 enum 类型。
  • equals() :判断是否为同一个对象。可以使用 == 来比较enum实例。

例:展示enum的基本方法

public class EnumMethodDemo {
    enum Color {RED, GREEN, BLUE;}
    enum Size {BIG, MIDDLE, SMALL;}
    public static void main(String args[]) {
        System.out.println("=========== Print all Color ===========");
        for (Color c : Color.values()) {
            System.out.println(c + " ordinal: " + c.ordinal());
        }
        System.out.println("=========== Print all Size ===========");
        for (Size s : Size.values()) {
            System.out.println(s + " ordinal: " + s.ordinal());
        }

        Color green = Color.GREEN;
        System.out.println("green name(): " + green.name());
        System.out.println("green getDeclaringClass(): " + green.getDeclaringClass());
        System.out.println("green hashCode(): " + green.hashCode());
        System.out.println("green compareTo Color.GREEN: " + green.compareTo(Color.GREEN));
        System.out.println("green equals Color.GREEN: " + green.equals(Color.GREEN));
        System.out.println("green equals Size.MIDDLE: " + green.equals(Size.MIDDLE));
        System.out.println("green equals 1: " + green.equals(1));
        System.out.format("green == Color.BLUE: %b\n", green == Color.BLUE);
    }
}

输出结果 

=========== Print all Color ===========
RED ordinal: 0
GREEN ordinal: 1
BLUE ordinal: 2
=========== Print all Size ===========
BIG ordinal: 0
MIDDLE ordinal: 1
SMALL ordinal: 2
green name(): GREEN
green getDeclaringClass(): class org.zp.javase.enumeration.EnumDemo$Color
green hashCode(): 460141958
green compareTo Color.GREEN: 0
green equals Color.GREEN: true
green equals Size.MIDDLE: false
green equals 1: false
green == Color.BLUE: false

枚举的特性

枚举的特性,归结起来就是一句话:

除了不能继承,基本上可以将 enum 看做一个常规的类

我们经常使用switch语句来写状态机。JDK7以后,switch已经支持 intcharStringenum 类型的参数。这几种类型的参数比较起来,使用枚举的switch代码更具有可读性

enum Signal {RED, YELLOW, GREEN}

public static String getTrafficInstruct(Signal signal) {
    String instruct = "信号灯故障";
    switch (signal) {
        case RED:
            instruct = "红灯停";
            break;
        case YELLOW:
            instruct = "黄灯请注意";
            break;
        case GREEN:
            instruct = "绿灯行";
            break;
        default:
            break;
    }
    return instruct;
}

 Day.java

public enum Day {
    SUNDAY(1),
    MONDAY(2),
    TUESDAY(3),
    WEDNESDAY(4),
    THURSDAY(5),
    FRIDAY(6),
    SATURDAY(7);

    private int value;


    // 私有构造
    private Day(int value) {
        this.value = value;
    }

    // 重写toString方法
    @Override
    public String toString() {
        switch (this) {
            case FRIDAY:
                return "Friday: " + value;
            case MONDAY:
                return "Monday: " + value;
            case SATURDAY:
                return "Saturday: " + value;
            case SUNDAY:
                return "Sunday: " + value;
            case THURSDAY:
                return "Thursday: " + value;
            case TUESDAY:
                return "Tuesday: " + value;
            case WEDNESDAY:
                return "Wednesday: " + value;
            default:
                return null;
        }
    }
}
  • toString方法能够将枚举对象转化成字符串并返回枚举常量名,例如:

System.out.println(Day.SUNDAY.toString());   // 打印:SUNDAY

  • valueOf方法能够根据枚举常量名返回枚举对象,例如:

Size s = Enum.valueOf(Day.class, "SUNDAY");

System.out.println(s.getAbbreviation());   // 打印:1

  • values方法可以返回一个包含全部枚举值的数组,例如:

Day[] values =Day.values();

EnumSet和EnumMap

Java 中提供了两个方便操作enum的工具类——EnumSet 和 EnumMap。

EnumSet 是枚举类型的高性能 Set 实现。它要求放入它的枚举常量必须属于同一枚举类型。
EnumMap 是专门为枚举类型量身定做的 Map 实现。虽然使用其它的 Map 实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用 EnumMap 会更加高效:它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值。这使得 EnumMap 的效率非常高。

Car.java

public enum Car {
    AUDI {
        @Override
        public int getPrice() {
            return 25000;
        }
    },
    MERCEDES {
        @Override
        public int getPrice() {
            return 30000;
        }
    },
    BMW {
        @Override
        public int getPrice() {
            return 20000;
        }
    };

    public abstract int getPrice();
}

EnumMap示例

import java.util.EnumMap;
 
public class EnumMapExample {
    public static void main(String[] args) {
        // Create an EnumMap that contains all constants of the Car enum.
        EnumMap cars = new EnumMap(Car.class);
        
        // Put some values in the EnumMap.
        cars.put(Car.BMW, Car.BMW.getPrice());
        cars.put(Car.AUDI, Car.AUDI.getPrice());
        cars.put(Car.MERCEDES, Car.MERCEDES.getPrice());
        
        // Print the values of an EnumMap.
        for(Car c: cars.keySet())
            System.out.println(c.name());
        
        System.out.println(cars.size());
        
        // Remove a Day object.
        cars.remove(Car.BMW);
        System.out.println("After removing Car.BMW, size: " + cars.size());
        
        // Insert a Day object.
        cars.put(Car.valueOf("BMW"), Car.BMW.getPrice());
        System.out.println("Size is now: " + cars.size());
    }
}

EnumSet示例

import java.util.EnumSet;
 
public class EnumSetExample {
    public static void main(String[] args) {
        // Create an EnumSet that contains all days of the week.
        EnumSet week = EnumSet.allOf(Day.class);
        
        // Print the values of an EnumSet.
        for(Day d: week)
            System.out.println(d.name());
        
        System.out.println(week.size());
        
        // Remove a Day object.
        week.remove(Day.FRIDAY);
        System.out.println("After removing Day.FRIDAY, size: " + week.size());
        
        // Insert a Day object.
        week.add(Day.valueOf("FRIDAY"));
        System.out.println("Size is now: " + week.size());
    }
}

枚举示例

package net.test.demo.api.constants;

import org.apache.commons.lang3.StringUtils;

public enum TrunkOperatorEnum {
  MOBILE(1, "移动", "mobile"),
  UNICOM(2, "联通", "unicom"),
  TELECOM(3, "电信", "telecom");

  private int id;
  private String name;
  private String nameEn;

  TrunkOperatorEnum(int id, String name, String nameEn) {
    this.id = id;
    this.name = name;
    this.nameEn = nameEn;
  }

  public int getId() {
    return id;
  }

  public String getName() {
    return name;
  }

  public String getNameEn() {
    return nameEn;
  }
  
  public static TrunkOperatorEnum getById(int id) {
    for (TrunkOperatorEnum item : TrunkOperatorEnum.values()) {
      if (item.getId() == id) {
        return item;
      }
    }
    return null;
  }

  /**
   * 根据中文名称返回数字
   *
   * @param name
   * @return
   */
  public static int getIdByName(String name) {
    int id = 4;
    for (TrunkOperatorEnum item : TrunkOperatorEnum.values()) {
      if (StringUtils.isNotEmpty(item.getName()) && item.getName().equals(name)) {
        id = item.getId();
        break;
      }
    }
    return id;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值