一. 什么是枚举
枚举是一种数据类型, 具有集合的一些特点, 可以存放多个元素, 但存储对象有限且固定, 枚举也有比较常见的使用场景, 如我们需要表达性别 (男, 女), 颜色(红, 黄, 蓝), 星期(星期一, 星期二... 星期日), 四季(春, 夏, 秋, 冬), 地理位置(东, 西, 南, 北), 方向(前, 后, 左, 右) 等, 这些场景都非常适合枚举.
二. 定义枚举
java 中使用 enum 来定义枚举, 和 class,interface 具有同样的等级,(注意是 enum, 而不是 Enum), 定义枚举可以有两种情况
第一种: 默认构造器(空构造器)
- public enum Quarter {
- SPRING, SUMMER, AUTUMN, WINTER;
- }
未定义成员变量和成员方法, 省略了 private Quarter() {}
- public enum Quarter {
- SPRING, SUMMER, AUTUMN, WINTER;
- private Quarter(){}
- }
简单说明一下: 枚举 enum 的构造器只能是 private
第二种: 定义了成员变量, 带参构造器
枚举可以定义成员变量, 包括成员属性, 方法, 抽象方法, 静态方法等
- public enum Quarter {
- SPRING("春"), SUMMER("夏"), AUTUMN("秋"), WINTER("冬");
- private Quarter(String name){
- this.name = name;
- }
- private String name;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- // 静态方法
- public static void printName(){
- System.out.println(Quarter.SUMMER);
- }
- // 抽象方法
- public abstract void printValue();
- }
注意: 枚举和类一样, 可以有多个构造器, 即有了一个带参构造器, 还可以有无参构造器, 编译是可以通过的.
除此之外:
枚举 enum 默认继承了 java.lang.Enum 类, 实现了 java.lang.Seriablizable 和 java.lang.Comparable 两个接口, 可序列化以及进行比较;
所有的枚举值都是常量, 默认采用了 public static final 进行了修饰, enum 不是类, 自然也不能被继承或实现;
枚举值必须在第一行, 否则编译出错;
三. 枚举常见用法
1. 获取枚举元素以及成员变量
- public static void main(String[] args) {
- // 获取枚举元素
- System.out.println(Quarter.SPRING);
- // 调用 toString()方法将枚举元素转化为 String 类型
- System.out.println(Quarter.SPRING.name());
- System.out.println(Quarter.SPRING.toString());
- // 获取成员变量
- System.out.println(Quarter.SPRING.getName());
- }
输出结果:
- SPRING
- SPRING
- SPRING
春
2. 枚举遍历
有时候我们需要将枚举元素都取出来作为查询条件, 此时就需要进行遍历, 通过调用 Quarter.values()方法
- public static void main(String[] args) {
- // 通过 values()方法得到 Quarter 元素的数组
- Quarter[] quarters = Quarter.values();
- List<String> quarterParam = new ArrayList<>(quarters.length);
- // 将数组中的元素存储到 List 集合 quarterParam 中
- for (Quarter quarter : quarters) {
- quarterParam.add(quarter.toString());
- }
- }
3. switch 条件判断
枚举的元素有限且固定, 通过 switch 做条件判断却是正好
- public static void main(String[] args){
- Quarter quarter = Quarter.AUTUMN;
- switch (quarter) {
- case SPRING:
- System.out.println("找到了, 是它:" + SPRING);
- break;
- case SUMMER:
- System.out.println("找到了, 是它:" + SUMMER);
- break;
- case AUTUMN:
- System.out.println("找到了, 是它:" + AUTUMN);
- break;
- case WINTER:
- System.out.println("找到了, 是它:" + WINTER);
- break;
- default:
- System.out.println("未找到");
- break;
- }
- }
执行后结果:
找到了, 是它: AUTUMN
简单说明一下: 其实此处不需要 default 的内容, 或者说将 WINTER 作为 default 即可, 因为枚举天然有类型限制, 你只能传递它已有的元素以及 null, 不过正常情况下都会提前判断传递的参数是否为 null, 当 switch 接收到 null 时会报 java.lang.NullPointerException.
4. 枚举比较
4.1. 判断是否相等
枚举判断两个元素是否相等直接使用 == 进行判断即可, 因为它非类, 也无法实例化, 存储位置自然也不会根据对象的不同而不同.
- public static void main(String[] args){
- System.out.println(Quarter.AUTUMN == Quarter.AUTUMN);
- System.out.println(Quarter.AUTUMN == Quarter.WINTER);
- }
执行结果:
true false
也可以通过 equals()方法进行比较, 不过没必要, 因为其底层也是通过 == 来实现的.
- public abstract class Enum<E extends Enum<E>>
- implements Comparable<E>, Serializable {
- //equals 比较
- public final boolean equals(Object other) {
- return this==other;
- }
- }
4.2. 顺序比较
通过 compareTo 进行枚举元素比较, 此处比较的是在枚举中元素的先后顺序, 返回的是位置序数的差值
- public static void main(String[] args){
- System.out.println(Quarter.AUTUMN.compareTo(Quarter.SPRING));
- System.out.println(Quarter.AUTUMN.compareTo(Quarter.WINTER));
- }
执行结果为:
2 -1
我们看一下 compareTo 方法
- public abstract class Enum<E extends Enum<E>>
- implements Comparable<E>, Serializable {
- // 元素在枚举中的序号
- private final int ordinal;
- // 可以看到 compareTo 方法返回的就是两个元素 ordinal 的差值
- public final int compareTo(E o) {
- Enum<?> other = (Enum<?>)o;
- Enum<E> self = this;
- if (self.getClass() != other.getClass() &&
- self.getDeclaringClass() != other.getDeclaringClass())
- throw new ClassCastException();
- return self.ordinal - other.ordinal;
- }
- }
5. 枚举也可也实现接口
- public interface WeatherInterface {
- // 获取温度
- public String getTemperature(Quarter quarter);
- }
- public enum Quarter implements WeatherInterface{
- SPRING("春"), SUMMER("夏"), AUTUMN("秋"), WINTER("冬");
- private Quarter(String name){
- this.name = name;
- }
- private String name;
- public String getName() {
- return name;
- }
- // 重写获取温度方法
- @Override
- public String getTemperature(Quarter quarter) {
- switch (quarter) {
- case SPRING:
- return "适中";
- case SUMMER:
- return "热";
- case AUTUMN:
- return "凉爽";
- case WINTER:
- return "寒冷";
- default:
- return "无法确定";
- }
- }
- }
但注意枚举不可继承其他类
- public class Pquarter {
- }
- // 无法编译通过
- public enum Quarter extends Pquarter {
- }
6. 使用接口来组织枚举
如果枚举太多也不好管理, 同时条理不够清晰, 我们可以通过接口来将多个相关枚举组织在一起进行管理,
- public interface Weather {
- enum Quarter implements Weather {
- SPRING, SUMMER, AUTUMN, WINTER;
- }
- enum Temperature implements Weather {
- MODERATE, HEAT, COOL, COLD
- }
- // 调用时直接通过 Weather.Quarter.SPRING 即可.
- }
四. 总结
本文主要介绍了枚举 enum 主要特点, 定义, 无参构造器, 有参构造器, 枚举的常用方法举例以及主要的应用场景, 若有不对之处, 请批评指正, 望共同进步, 谢谢!
来源: https://www.cnblogs.com/LiaHon/p/11283026.html