《深入探秘Java中的枚举:掌握Enum的魔力》

目录

  • 📝 枚举
    • 枚举的定义
    • 枚举的使用
      • 1、表示一组固定常量
      • 2、实现接口
      • 3、枚举与策略模式
      • 4、EnumSet
      • 5、EnumMap
  • 📎 参考文章

😀 准备好了吗?让我们一起步入这座Java神奇的城堡,探寻枚举(Enum)这个强大工具的奥秘。

📝 枚举

枚举(Enum)是Java中的一个特殊数据类型,继承自 java.lang.Enum,用于定义一组固定的常量。它被用来表示一组有名字的常量,使用起来比定义一组整型或字符串常量更加安全和简洁。

枚举也是一种特殊的类,那它其实是可以定义在一个类的内部的,这样它的作用域就可以限定于这个外部类中使用。

枚举的定义

枚举使用enum关键字来定义。

public enum Day{SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

编译后的字节码文件:

public final class Day extends Enum<Day> {// 定义枚举常量,静态最终字段(static final),每个常量都有一个唯一的实例public static final Day SUNDAY = new Day("SUNDAY", 0);public static final Day MONDAY = new Day("MONDAY", 1);public static final Day TUESDAY = new Day("TUESDAY", 2);public static final Day WEDNESDAY = new Day("WEDNESDAY", 3);public static final Day THURSDAY = new Day("THURSDAY", 4);public static final Day FRIDAY = new Day("FRIDAY", 5);public static final Day SATURDAY = new Day("SATURDAY", 6);// 包含所有枚举常量的数组,供 values() 方法使用private static final Day[] $VALUES = { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };// 枚举常量的字段,存储名称和序号private final String name;private final int ordinal;// 私有构造函数,防止外部实例化private Day(String name, int ordinal) {this.name = name;this.ordinal = ordinal;}// 返回枚举常量的名称public String name() {return name;}// 返回枚举常量的序号public int ordinal() {return ordinal;}// 返回所有枚举常量的数组的副本public static Day[] values() {return (Day[]) $VALUES.clone();}// 根据名称返回对应的枚举常量public static Day valueOf(String name) {return (Day) Enum.valueOf(Day.class, name);}
}

在其他类中定义:

public class Schedule {//定义枚举public enum Day{SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}private Day day;public Schedule(Day day){this.day = day ;    }public Day getToday() {return today;}public void setToday(Day today) {this.today = today;}public void printTask() {switch (today) {case MONDAY:System.out.println("今天的任务:参加团队会议。");break;case TUESDAY:System.out.println("今天的任务:编写项目文档。");break;case WEDNESDAY:System.out.println("今天的任务:代码审查和修复漏洞。");break;case THURSDAY:System.out.println("今天的任务:实现新功能。");break;case FRIDAY:System.out.println("今天的任务:部署应用程序。");break;case SATURDAY:case SUNDAY:System.out.println("今天的任务:休息和充电。");break;}}public static void main(String[] args) {// 创建一个 Schedule 对象,表示今天是星期一Schedule schedule = new Schedule(Day.MONDAY);schedule.printTask();// 改变今天的日期为星期五schedule.setToday(Day.FRIDAY);schedule.printTask();}}

枚举也是不可变类,一旦枚举常量被创建,它们的状态(即枚举的实例)是不能被改变的。所以这可以确保Java虚拟机中仅有一个常量对象。

一般比较两个枚举对象时,采用==运算符比较。

  • ==运算符比较的时候,如果两个对象都为 null,并不会发生 NullPointerException,而 equals() 方法则会.

  • ==运算符会在编译时进行检查,如果两侧的类型不匹配,会提示错误,而 equals() 方法则不会。


枚举的使用

1、表示一组固定常量

枚举通常用于表示一组固定的常量,例如星期几、颜色、方向等。

public enum Day {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

2、实现接口

枚举可以实现接口,允许为每个枚举常量定义不同的行为。

// 定义一个接口,声明获取最大速度的方法
public interface Speed {int getMaxSpeed();
}// 定义一个枚举类,表示不同的交通工具,并实现 Speed 接口
public enum Vehicle implements Speed {CAR {@Overridepublic int getMaxSpeed() {return 150; // 汽车的最大速度}},MOTORCYCLE {@Overridepublic int getMaxSpeed() {return 180; // 摩托车的最大速度}},BICYCLE {@Overridepublic int getMaxSpeed() {return 30; // 自行车的最大速度}}
}public class EnumExample {public static void main(String[] args) {// 遍历所有交通工具并输出其最大速度for (Vehicle vehicle : Vehicle.values()) {System.out.println(vehicle + " 的最大速度是 " + vehicle.getMaxSpeed() + " km/h.");}}
}

3、枚举与策略模式

// 定义一个枚举类,表示不同的打折策略
public enum DiscountStrategy {NO_DISCOUNT {@Overridepublic double applyDiscount(double price) {return price; // 不打折}},SUMMER_SALE {@Overridepublic double applyDiscount(double price) {return price * 0.9; // 夏季促销打折 10%}},WINTER_SALE {@Overridepublic double applyDiscount(double price) {return price * 0.8; // 冬季促销打折 20%}};// 抽象方法,应用打折策略public abstract double applyDiscount(double price);
}public class EnumExample {public static void main(String[] args) {double originalPrice = 100.0; // 原始价格DiscountStrategy strategy = DiscountStrategy.SUMMER_SALE; // 选择夏季促销打折策略double discountedPrice = strategy.applyDiscount(originalPrice); // 计算打折后的价格System.out.println("原始价格: " + originalPrice); // 输出: Original Price: 100.0System.out.println("打折后的价格: " + discountedPrice); // 输出: Discounted Price: 90.0}
}

4、EnumSet

EnumSet 是一个专门处理枚举类型的集合实现(Set接口)。

EnumSet 的创建和使用

EnumSet 是一个抽象类,所以创建 EnumSet 时不能使用 new 关键字。不过,EnumSet 提供了很多有用的静态工厂方法。

  • EnumSet.noneOf(Class<E> elementType): 创建一个空的 EnumSet,其中 E 是枚举类型。

  • EnumSet.allOf(Class<E> elementType): 创建一个包含指定枚举类型所有枚举常量的 EnumSet

  • EnumSet.of(E e): 创建一个只包含指定枚举常量的 EnumSet

  • EnumSet.of(E e1, E e2, E... rest): 创建一个包含指定枚举常量的 EnumSet

  • EnumSet.range(E from, E to): 创建一个包含指定范围内所有枚举常量的 EnumSet

示例:

import java.util.EnumSet;// 定义一个枚举类
public enum Day {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}public class EnumSetExample {public static void main(String[] args) {// 创建一个包含所有星期几的 EnumSetEnumSet<Day> allDays = EnumSet.allOf(Day.class);System.out.println("All days: " + allDays);// 创建一个包含指定枚举常量的 EnumSetEnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);System.out.println("Weekend: " + weekend);// 创建一个空的 EnumSetEnumSet<Day> noDays = EnumSet.noneOf(Day.class);System.out.println("No days: " + noDays);// 创建一个包含某个范围内枚举常量的 EnumSetEnumSet<Day> weekDays = EnumSet.range(Day.MONDAY, Day.FRIDAY);System.out.println("Weekdays: " + weekDays);// 向 EnumSet 添加元素(不允许直接添加,需使用添加方法)noDays.add(Day.MONDAY);noDays.add(Day.FRIDAY);System.out.println("No days after adding: " + noDays);// 执行集合操作EnumSet<Day> holidays = EnumSet.of(Day.SATURDAY, Day.SUNDAY);EnumSet<Day> workDays = EnumSet.complementOf(holidays);System.out.println("Workdays: " + workDays);}
}

5、EnumMap

EnumMap 是 Java Collections Framework 中的一个特殊的映射实现,专门用于枚举类型的映射。它是 Map 接口的一个实现,优化了对枚举类型的支持,提供了高效的键值对操作。

EnumMap 的创建和使用

EnumMap 不是一个抽象类,需要用 new 关键字来创建。

import java.util.EnumMap;
import java.util.Map;// 定义一个枚举类
public enum Day {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}public class EnumMapExample {public static void main(String[] args) {// 创建一个 EnumMap,键为 Day 枚举,值为 String 类型EnumMap<Day, String> dayMap = new EnumMap<>(Day.class);// 向 EnumMap 中添加键值对dayMap.put(Day.MONDAY, "Workday");dayMap.put(Day.SATURDAY, "Weekend");dayMap.put(Day.SUNDAY, "Weekend");// 输出 EnumMap 内容System.out.println("Day Map: " + dayMap);// 访问指定键的值System.out.println("Monday: " + dayMap.get(Day.MONDAY)); // 输出: Workday// 检查是否包含某个键System.out.println("Contains Saturday? " + dayMap.containsKey(Day.SATURDAY)); // 输出: true// 检查是否包含某个值System.out.println("Contains Weekend value? " + dayMap.containsValue("Weekend")); // 输出: true// 遍历 EnumMap 并输出键值对for (Map.Entry<Day, String> entry : dayMap.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());}// 移除某个键值对dayMap.remove(Day.SUNDAY);System.out.println("Day Map after removing Sunday: " + dayMap);}
}

📎 参考文章

  • Java 枚举

  • 菜鸟教程

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1487322.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

grafana对接zabbix数据展示

目录 1、初始化、安装grafana 2、浏览器访问 3、安装zabbix 4、zabbix数据对接grafana 5、如何导入模板&#xff1f; ① 设置键值 ② 在zabbix web端完成自定义监控项 ③ garafana里添加nginx上面的的三个监控项 6、如何自定义监控项&#xff1f; 以下实验沿用上一篇z…

Python学习笔记44:游戏篇之外星人入侵(五)

前言 上一篇文章中&#xff0c;我们成功的设置好了游戏窗口的背景颜色&#xff0c;并且在窗口底部中间位置将飞船加载出来了。 今天&#xff0c;我们将通过代码让飞船移动。 移动飞船 想要移动飞船&#xff0c;先要明白飞船位置变化的本质是什么。 通过上一篇文章&#xff0…

vue上传Excel文件并直接点击文件列表进行预览

本文主要内容&#xff1a;用elementui的Upload 组件上传Excel文件&#xff0c;上传后的列表采用xlsx插件实现点击预览表格内容效果。 在项目中可能会有这样的需求&#xff0c;有很多种方法实现。但是不想要跳转外部地址&#xff0c;所以用了xlsx插件来解析表格&#xff0c;并展…

使用 vSphere vCenter 管理 ESXi

使用 vSphere vCenter 管理 ESXi 1、新建数据中心 在 vSphere Client 中&#xff0c;左上角图标&#xff0c;进入 “清单”&#xff0c;鼠标右键名称&#xff0c;新建数据中心。 输入数据中心名称&#xff0c;我这里直接使用默认值&#xff0c;点击确定。 2、往数据中心中添加…

Linux epoll 机制——原理图解与源码实现分析

epoll概述 epoll是Linux内核为处理大批量文件描述符而作了改进的poll&#xff0c;它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。 epoll可以理解为event poll&#xff0c;它是一种事件驱动的I/O模型&#xff0c;可以用来替代传统的select和poll模型…

leetcode-98. 验证二叉搜索树

题目描述 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&…

功能性的安全性保障:TOKEN鉴权校验

1. 引言 在软件开发过程中&#xff0c;确保系统的安全性是至关重要的一环。它不仅关乎保护用户数据的完整性和隐私性&#xff0c;也是维护系统稳定运行的基石。我认为&#xff0c;从宏观角度审视&#xff0c;软件开发的安全性保障主要可分为两大类&#xff1a;功能性的安全性保…

Golang | Leetcode Golang题解之第275题H指数II

题目&#xff1a; 题解&#xff1a; func hIndex(citations []int) int {n : len(citations)return n - sort.Search(n, func(x int) bool { return citations[x] > n-x }) }

JDBC操作MySQL数据

一准备、 1、首先在IDEA中导入导入包&#xff1a;mysql-connector-java-8.0.23 2、写初始化语句 &#xff08;1&#xff09;在目录下找到driver类 &#xff08;2&#xff09;在JDBCUtil函数中把驱动器的类路径改掉 ①打开driver类 ②按住类名 Driver用快捷键 CtrlAltshiftC …

AIGC的神秘面纱——利用人工智能生成内容改变我们的生活

近年来&#xff0c;人工智能生成内容&#xff08;AIGC&#xff09;正在迅速改变我们与数字世界互动的方式。从自动写作到图像生成&#xff0c;AIGC正逐渐走进我们的日常生活。它不仅提高了效率&#xff0c;还为创意和商业活动带来了新的可能性。让我们一起来探索AIGC的世界&…

17.jdk源码阅读之LinkedBlockingQueue

1. 写在前面 LinkedBlockingQueue 是 Java 并发包中的一个重要类&#xff0c;常用于生产者-消费者模式等多线程编程场景。上篇文章我们介绍了ArrayBlockingQueue&#xff0c;并且与LinkedBlockingQueue做了简单的对比&#xff0c;这篇文章我们来详细分析下LinkedBlockingQueue…

从零开始构建你的第一个Python Web应用

在本文中&#xff0c;我们将带领你从零开始构建一个简单的Python Web应用。不需要任何先验知识&#xff0c;我们会一步步地指导你完成设置、框架选择、代码编写到部署的整个过程。无论你是Web开发新手还是希望扩展技能的老手&#xff0c;这篇文章都将为你提供一个实践操作的起点…

Spring-Aop源码解析(二)

书接上文&#xff0c;上文说到&#xff0c;specificInterceptors 不为空则执行createProxy方法创建代理对象&#xff0c;即下图的createProxy方法开始执行&#xff0c;生成代理对象&#xff0c;生成代理对象有两种方式&#xff0c;JDK和CGLIB。 createAopProxy就是决定使用哪…

【数据结构 | 哈希表】一文了解哈希表(散列表)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

昇思学习打卡-22-生成式/DCGAN生成漫画头像

文章目录 DCGAN网络数据处理构造网络生成器判别器损失函数优化器 结果展示 我们将学习DCGAN网络如何数据处理、设置网络&#xff0c;包括生成器、判别器、损失函数、优化器等。 DCGAN网络 DCGAN&#xff08;深度卷积对抗生成网络&#xff0c;Deep Convolutional Generative Ad…

windows下运行sh文件

1、打开git bash 2、进入sh文件所在文件夹&#xff0c;使用sh xx.sh运行

普发Pfeiffer TPG300手侧配置安装操作技术资疗包含

普发Pfeiffer TPG300手侧配置安装操作技术资疗包含

学习笔记:MySQL数据库操作2

1. 建库建表 创建数据库 mydb8_worker。使用该数据库 mydb8_worker。创建职工表 t_worker&#xff0c;字段包括&#xff1a; department_id: 部门号&#xff0c;整型&#xff0c;不允许为空。worker_id: 职工号&#xff0c;主键&#xff0c;整型&#xff0c;不允许为空。worke…

硬盘数据恢复的基本原理是什么 硬盘数据恢复教程

无论是电脑硬盘&#xff0c;还是日常办公过程中使用系统硬盘&#xff0c;都是由多个存储空间组成的。如果这些存储空间中的信息被删除了&#xff0c;那内部的文件也会跟着消失。下面&#xff0c;小编就以“硬盘数据恢复工具恢复原理&#xff0c;硬盘数据恢复教程”这两个问题为…

昇思25天学习打卡营第18天 | DCGAN生成漫画头像

探索DCGAN在生成动漫头像的实用性 通过深入学习和实践DCGAN&#xff08;Deep Convolutional Generative Adversarial Networks&#xff09;&#xff0c;我对这种深度学习模型在生成动漫头像方面的应用有了更全面的理解。DCGAN作为一种改进的GAN模型&#xff0c;通过在生成器和…