Java 枚举
1. 概念
enum的全称为 enumeration, 是 JDK 1.5 中引入的新特性。枚举可以集中统一地管理项目中的常量,通常用来表示错误码,状态机等。我们有时候会用 public static final来定义某种状态,枚举与之不同的是可以将各种状态值进行分类,只有同一类型的值才能比较,进而规范了这些状态值的使用。枚举值默认为从0开始的有序数值。
· 创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum(定义如下)
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { private final String name; private final int ordinal; protected Enum(String name, int ordinal) { this.name = name; this.ordinal = ordinal; } ... }
· 枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中
public enum Color{WHITE, BLACK;}; //这段代码实际上调用了2次 Enum(String name, int ordinal): new Enum<WeekDay>("WHITE",0); new Enum<WeekDay>("BLACK",1);
2.遍历、switch 等常用操作
public class Test { public enum Operation {PLUS, MINUS, TIMES, DIVIDE} public static void main(String[] args) { for(Operation op : Operation.values()) { System.out.print(op.toString() + " "); } System.out.println(); Operation op = Operation.MINUS; switch(op){ case PLUS: System.out.println("This is " + Operation.PLUS); break; case MINUS: System.out.println("This is " + Operation.MINUS); break; case TIMES: System.out.println("This is " + Operation.TIMES); break; default: System.out.println("This is " + Operation.DIVIDE); break; } } }
运行结果
PLUS MINUS TIMES DIVIDE
This is MINUS
3. enum自定义属性和方法
Java允许在枚举中添加任意的方法和域,并实现任意的接口。
public class Test { public enum Operation { // 通过括号赋值,需有对应的构造函数.赋值必须都赋值或都不赋值! // 给每个枚举常量提供不同的数据操作行为 PLUS("+", 1) { double apply(double x, double y){return x + y;} }, MINUS("-", 2) { double apply(double x, double y){return x - y;} }, TIMES("*", 3) { double apply(double x, double y){return x * y;} }, DIVIDE("/",4) { double apply(double x, double y){return x / y;} }; private final String symbol; private int index; // 自定义枚举值的位置,防止新增枚举值后顺序打乱 Operation(String symbol, int index){ this.symbol = symbol; this.index = index; } public int getIndex() { return index; } public String toString() { return symbol; } abstract double apply(double x, double y); // 自定义方法,定义为抽象方法后,每个枚举值都要实现该方法 } public static void main(String[] args) { double x = 6.0; double y = 2.0; for (Operation op : Operation.values()) System.out.printf("(%d) %.0f %s %.0f = %.0f%n", op.getIndex(), x, op, y, op.apply(x,y)); } }
运行结果
(1) 6 + 2 = 8
(2) 6 - 2 = 4
(3) 6 * 2 = 12
(4) 6 / 2 = 3
enum可以实现接口,但不能继承其他类(它已经默认继承Enum类了)
interface Operation { double apply(double x,double y); } enum BasicOperation implements Operation { PLUS("+") { public double apply(double x,double y) { return x + y; } }, MINUS("-") { public double apply(double x,double y) { return x - y; }}, TIMES("*") { public double apply(double x,double y) { return x * y; }}, DIVIDE("/") {public double apply(double x,double y) { return x / y; }}; private final String symbol; BasicOperation(String symbol) { this.symbol = symbol; } @Override public String toString() { return symbol; } } enum ExtendedOperation implements Operation { EXP("^") {public double apply(double x,double y) { return Math.pow(x,y);}}, REMAINDER("%") {public double apply(double x,double y) {return x % y;}}; private final String symbol; ExtendedOperation(String symbol) { this.symbol = symbol; } @Override public String toString() { return symbol; } } public class Test { public static void main(String[] args) { double x = 6; double y = 2; test(ExtendedOperation.class,x,y); } private static <T extends Enum<T> & Operation> void test( Class<T> opSet,double x, double y) { for (Operation op : opSet.getEnumConstants()) { System.out.printf("%.0f %s %.0f = %.0f%n", x, op, y, op.apply(x,y)); } } }
运行结果
6 ^ 2 = 36
6 % 2 = 0
4. EnumSet和EnumMap
Java中提供了两个方便操作enum的工具类——EnumSet和EnumMap。
EnumSet 是枚举类型的高性能Set实现。它要求放入它的枚举常量必须属于同一枚举类型。
EnumMap是专门为枚举类型量身定做的Map实现。虽然使用其它的Map实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用EnumMap会更加高效:它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以EnumMap使用数组来存放与枚举类型对应的值。这使得EnumMap的效率非常高。
public class Test { public enum Operation {PLUS, MINUS, TIMES, DIVIDE} public static void main(String[] args) { System.out.println("EnumSet:"); EnumSet<Operation> opSet = EnumSet.allOf(Operation.class); for(Operation op : opSet) { System.out.print(op.toString() + " "); } System.out.println("\nEnumMap:"); EnumMap<Operation, String> opMap = new EnumMap(Operation.class); opMap.put(Operation.PLUS, "+"); opMap.put(Operation.MINUS, "-"); Iterator<Map.Entry<Operation, String>> itr = opMap.entrySet().iterator(); for(; itr.hasNext(); ) { Map.Entry<Operation, String> op = itr.next(); System.out.print(op.getKey() + op.getValue() + " "); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix