读书笔记-《ON JAVA 中文版》-摘要25[第二十二章 枚举]

文章目录

  • 第二十二章 枚举
    • 1. 基本功能
      • 1.1 基本 enum 特性
    • 2. 方法添加
      • 2.1 方法添加
      • 2.2 覆盖 enum 的方法
    • 3 switch 语句中的 enum
    • 4. values 方法的神秘之处
    • 5. 实现而非继承
    • 6. 随机选择
    • 7. 使用接口组织枚举
    • 8. 使用 EnumSet 替代 Flags
    • 9. 使用 EnumMap
    • 10. 常量特定方法
    • 11. 本章小结

第二十二章 枚举

关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用。这是一种非常有用的功能

1. 基本功能

1.1 基本 enum 特性

package enums;enum Shrubbery {GROUND, CRAWLING, HANGING}public class EnumClass {public static void main(String[] args) {for (Shrubbery s : Shrubbery.values()) { // 实例 .values() 方法返回 enum 实例的数组System.out.println(s + " ordinal: " +s.ordinal()); // ordinal() 方法返回 enum 实例在声明时的次序,从 0 开始System.out.print(s.compareTo(Shrubbery.CRAWLING) + " ");System.out.print(s.equals(Shrubbery.CRAWLING) + " ");System.out.println(s == Shrubbery.CRAWLING);System.out.println(s.getDeclaringClass()); // 其所属的 enum 类System.out.println(s.name()); // 获取值System.out.println("********************");}for (String s :"HANGING CRAWLING GROUND AA".split(" ")) {// valueOf() 是在 Enum 中定义的 static 方法,// 它根据给定的名字返回相应的 enum 实例,// 如果不存在给定名字的实例,将会抛出异常Shrubbery shrub = Enum.valueOf(Shrubbery.class, s);System.out.println(shrub);}}
}

输出:

GROUND ordinal: 0
-1 false false
class enums.Shrubbery
GROUND
********************
CRAWLING ordinal: 1
0 true true
class enums.Shrubbery
CRAWLING
********************
HANGING ordinal: 2
1 false false
class enums.Shrubbery
HANGING
********************
HANGING
CRAWLING
GROUND
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant enums.Shrubbery.AAat java.lang.Enum.valueOf(Enum.java:238)at enums.EnumClass.main(EnumClass.java:32)

2. 方法添加

2.1 方法添加

除了不能继承自一个 enum 之外,基本上可以将 enum 看作一个常规的类。也就是说可以向 enum 中添加方法。enum 甚至可以有 main() 方法。

一般来说,我们希望每个枚举实例能够返回对自身的描述,而不仅仅只是默认的 toString() 实现,这只能返回枚举实例的名字。为此,你可以提供一个构造器,专门负责处理这个额外的信息,然后添加一个方法,返回这个描述信息。

package enums;public enum OzWitch {WEST("Miss Gulch, aka the Wicked Witch of the West"),NORTH("Glinda, the Good Witch of the North"),EAST("Wicked Witch of the East, wearer of the Ruby " +"Slippers, crushed by Dorothy's house"),SOUTH("Good by inference, but missing");private String description;OzWitch(String description) {this.description = description;}public String getDescription() {return description;}public static void main(String[] args) {for (OzWitch witch : OzWitch.values()) {System.out.println(witch + witch.getDescription());}}
}

输出:

WESTMiss Gulch, aka the Wicked Witch of the West
NORTHGlinda, the Good Witch of the North
EASTWicked Witch of the East, wearer of the Ruby Slippers, crushed by Dorothy's house
SOUTHGood by inference, but missing

2.2 覆盖 enum 的方法

package enums;import java.util.stream.Stream;public enum SpaceShip {SCOUT, CARGO, TRANSPORT,CRUISER, BATTLESHIP, MOTHERSHIP;@Overridepublic String toString() {String id = name();String lower = id.substring(1).toLowerCase();return id.charAt(0) + lower;}public static void main(String[] args) {Stream.of(values()).forEach(System.out::println);}
}

输出:

Scout
Cargo
Transport
Cruiser
Battleship
Mothership

3 switch 语句中的 enum

在 switch 中使用 enum,是 enum 提供的一项非常便利的功能。一般来说,在 switch 中只能使用整数值,而枚举实例天生就具备整数值的次序,并且可以通过 ordinal() 方法取得其次序(显然编译器帮我们做了类似的工作)。

package enums;enum Signal {GREEN, YELLOW, RED,}public class TrafficLight {Signal color = Signal.RED;public void change() {switch (color) {case RED:color = Signal.GREEN;break;case GREEN:color = Signal.YELLOW;break;case YELLOW:color = Signal.RED;break;}}@Overridepublic String toString() {return "The traffic light is " + color;}public static void main(String[] args) {TrafficLight t = new TrafficLight();for (int i = 0; i < 5; i++) {System.out.println(t);t.change();}}
}

输出:

The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED
The traffic light is GREEN

4. values 方法的神秘之处

前面已经提到,编译器为你创建的 enum 类都继承自 Enum 类。然而,如果你研究一下 Enum 类就会发现,它并没有 values() 方法。答案是,values() 是由编译器添加的 static 方法。

5. 实现而非继承

所有的 enum 都继承自 Java.lang.Enum 类。由于 Java 不支持多重继承,所以你的 enum 不能再继承其他类:

enum NotPossible extends Pet { ... // Won't work

然而,在我们创建一个新的 enum 时,可以同时实现一个或多个接口。

6. 随机选择

package onjava;import java.util.Random;public class Enums {private static Random rand = new Random(47);public static <T extends Enum<T>> T random(Class<T> ec) {return random(ec.getEnumConstants());}public static <T> T random(T[] values) {return values[rand.nextInt(values.length)];}
}
package enums;import onjava.Enums;enum Activity {SITTING, LYING, STANDING, HOPPING,RUNNING, DODGING, JUMPING, FALLING, FLYING
}public class RandomTest {public static void main(String[] args) {for (int i = 0; i < 20; i++) {Activity random = Enums.random(Activity.class);System.out.print(random + " ");}}
}

输出:

STANDING FLYING RUNNING STANDING RUNNING STANDING LYING DODGING SITTING RUNNING HOPPING HOPPING HOPPING RUNNING STANDING LYING FALLING RUNNING FLYING LYING 

7. 使用接口组织枚举

在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组,可以达到将枚举元素分类组织的目的。

package enums.menu;public interface Food {enum Appetizer implements Food {SALAD, SOUP, SPRING_ROLLS;}enum MainCourse implements Food {LASAGNE, BURRITO, PAD_THAI,LENTILS, HUMMOUS, VINDALOO;}enum Dessert implements Food {TIRAMISU, GELATO, BLACK_FOREST_CAKE,FRUIT, CREME_CARAMEL;}enum Coffee implements Food {BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,LATTE, CAPPUCCINO, TEA, HERB_TEA;}
}
package enums.menu;
import static enums.menu.Food.*;public class TypeOfFood {public static void main(String[] args) {// 所有东西都是某种类型的 FoodFood food = Appetizer.SALAD;food = MainCourse.LASAGNE;food = Dessert.GELATO;food = Coffee.CAPPUCCINO;}
}

8. 使用 EnumSet 替代 Flags

Java SE5 引入 EnumSet,是为了通过 enum 创建一种替代品,以替代传统的基于 int 的“位标志”。这种标志可以用来表示某种“开/关”信息。

EnumSet 中的元素必须来自一个 enum。

下面的 enum 表示在一座大楼中,警报传感器的安放位置:

package enums;public enum AlarmPoints {STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3,OFFICE4, BATHROOM, UTILITY, KITCHEN
}

然后,我们用 EnumSet 来跟踪报警器的状态:

package enums;import java.util.EnumSet;import static enums.AlarmPoints.*;public class EnumSets {public static void main(String[] args) {// 创建一个空的 EnumSetEnumSet<AlarmPoints> points = EnumSet.noneOf(AlarmPoints.class);// 添加元素points.add(BATHROOM);System.out.println("add:" + points);points.addAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));System.out.println("addAll:" + points);points = EnumSet.allOf(AlarmPoints.class);System.out.println("EnumSet.allOf:" + points);points.removeAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));System.out.println("removeAll:" + points);points.removeAll(EnumSet.range(OFFICE1, OFFICE4));System.out.println("removeAll-EnumSet.range:" + points);points = points.complementOf(points);System.out.println("complementOf:" + points);}
}

输出:

add:[BATHROOM]
addAll:[STAIR1, STAIR2, BATHROOM, KITCHEN]
EnumSet.allOf:[STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, BATHROOM, UTILITY, KITCHEN]
removeAll:[LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, BATHROOM, UTILITY]
removeAll-EnumSet.range:[LOBBY, BATHROOM, UTILITY]
complementOf:[STAIR1, STAIR2, OFFICE1, OFFICE2, OFFICE3, OFFICE4, KITCHEN]

9. 使用 EnumMap

EnumMap 是一种特殊的 Map,它要求其中的键(key)必须来自一个 enum。

package enums;import java.util.*;import static enums.AlarmPoints.*;interface Command {void action();
}public class EnumMaps {public static void main(String[] args) {EnumMap<AlarmPoints, Command> em = new EnumMap<>(AlarmPoints.class);em.put(KITCHEN,() -> System.out.println("Kitchen fire!"));em.put(BATHROOM,() -> System.out.println("Bathroom alert!"));for (Map.Entry<AlarmPoints, Command> e : em.entrySet()) {System.out.print(e.getKey() + ": ");e.getValue().action();}try { // If there's no value for a particular key:em.get(UTILITY).action();} catch(Exception e) {System.out.println("Expected: " + e);}}
}

10. 常量特定方法

Java 的 enum 有一个非常有趣的特性,即它允许程序员为 enum 实例编写方法,从而为每个 enum 实例赋予各自不同的行为。要实现常量相关的方法,你需要为 enum 定义一个或多个 abstract 方法,然后为每个 enum 实例实现该抽象方法。

package enums;public enum ConstantSpecificMethod {DATE_TIME {@Overridevoid getInfo() {System.out.println("DATE_TIME");}},CLASSPATH {@Overridevoid getInfo() {System.out.println("CLASSPATH");}};abstract void getInfo();public static void main(String[] args) {for (ConstantSpecificMethod v : values()) {v.getInfo();}}
}

调用 getInfo() 方法时,体现出多态的行为。

11. 本章小结

虽然枚举类型本身并不是特别复杂,但还是将本章安排在全书比较靠后的位置,这是因为,程序员可以将 enum 与 Java 语言的其他功能结合使用,例如多态、泛型和反射。
在这里插入图片描述
(图网,侵删)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【操作系统笔记】链接阶段ELF文件

链接阶段&#xff1a;符号解析 链接阶段主要包含&#xff1a; 符号解析重定位 一般情况下&#xff0c;每个 C 文件可以看成一个程序模块&#xff0c;比如下边的main.c就是一个程序模块 #include <stdio.h>extern int shared; int sum(int *a, int n); int array[2] …

springcloud3 分布式事务-seata的四种模式总结以及异地容灾

一 seata四种模式比较 1.1 seata的4种模式比较 二 seata的高可用 2.1架构 1.建TC服务集群非常简单&#xff0c;启动多个TC服务&#xff0c;注册到nacos即可。 2.做异地多机房容灾&#xff0c;比如一个TC集群在上海&#xff0c;另一个TC集群在杭州&#xff0c; 3.微服务基…

TuyaLink 快速入门教程

通过本入门教程&#xff0c;大家能了解到如何在涂鸦 IoT 开发平台上使用 TuyaLink 完成智能设备接入。并通过 Java 程序&#xff0c;在 IntelliJ IDEA 中使用 TuyaLink 的 GitHub Demo 工程&#xff0c;对一个电工开关设备&#xff0c;实现基本的数据上报下发功能。 准备工作 …

jmeter基础压力教程

Jmeter基础压力测试教程 一、安装Jmeter&#xff1b; 安装需求&#xff1a;1. JDK 8.0.91安装包&#xff08;最新即可&#xff0c;配置环境变量&#xff09; 2. Badboy2.25脚本录制工具&#xff08;注&#xff1a;Jmeter3.0与badboy2.0不兼容&#xff09; Jmerter安装包…

【数据库系统概论】关系数据库中的关系数据结构

前言关系关系模式关系数据库关系模型的存储结构感谢 &#x1f496; 前言 上一篇文章【数据库系统概论】数据模型介绍了数据库系统中的数据模型的基本概念。其中提到了关系模型是最重要的一种数据模型。下面将介绍支持关系模型的数据库系统——关系数据库。 按照数据模型的三大…

C++之std::holds_alternative、std::get、std::variant应用实例(二百一十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

阿里云产品试用系列-Serverless 应用引擎 SAE

Serverless 应用引擎 SAE&#xff08;Serverless App Engine&#xff09;是一个全托管、免运维、高弹性的通用 PaaS平台。SAE 支持 Spring Boot、Spring Cloud、Dubbo、HSF、Web 应用和 XXL-JOB、ElasticJob任务的全托管&#xff0c;零改造迁移、无门槛容器化、并提供了开源侧诸…

VUE3写后台管理(3)

VUE3写后台管理&#xff08;3&#xff09; 1.环境1.node2.vite3.Element-plus4.vue-router5.element icon6.less7.vuex8.vue-demi9.mockjs10.axios11.echarts 2.首页1.布局Main2.头部导航栏CommonHeader3.左侧菜单栏CommonLeft4.首页Home1.从后端获取数据显示到前端table的三种…

vue动态修改浏览器title和icon图标

vue动态修改浏览器title和icon图标 实例代码 setTitleIcon(){var link document.querySelector("link[rel*icon]") || document.createElement(link);link.type image/x-icon;link.rel shortcut icon;link.href /002.png; // 图片放public目录document.getElem…

SSM - Springboot - MyBatis-Plus 全栈体系(十)

第二章 SpringFramework 五、Spring AOP 面向切面编程 4. Spring AOP 框架介绍和关系梳理 AOP是一种区别于OOP的编程思维&#xff0c;用来完善和解决OOP的非核心代码冗余和不方便统一维护问题&#xff01;代理技术&#xff08;动态代理|静态代理&#xff09;是实现AOP思维编…

红黑树的定义和性质以及插入、删除操作

1.红黑树发明的原因 分析二叉排序树&#xff0c;平衡二叉树&#xff0c;红黑树的算法效率&#xff1a; BSTAVL TreeRed-Black Tree时间196019621972时间复杂度&#xff08;增删查&#xff09; O ( n ) O(n) O(n) O ( l o g 2 n ) O(log_2n) O(log2​n) O ( l o g 2 n ) O(log…

激光雷达录制pcap类型的包

查看IP 上图中的eno1就是网卡名&#xff0c;就可以使用如下命令录制 sudo tcpdump -i eno1 host 192.168.1.200 -w lidar.pcap-i 后面是网卡名&#xff0c;host 后面是ip&#xff0c;-w后是pcap包名称。

Ubuntu 22.04安装过程

iso下载地址 Ubuntu Releases 1.进入引导菜单 选择Try or Install Ubuntu Server安装 2.选择安装语言 默认选择English 3.选择键盘布局 默认即可 4.选择安装服务器版本 最小化安装 5.配置网络 选择ipv4 选择自定义 DHCP也可 6.配置代理 有需要可以配置 这里跳过 7.软件源 …

群晖 Docker版qbittorrent 下载显示错误 解决方法

这些天在折腾AIO玩&#xff0c;PVE虚拟机底层&#xff0c;核显直通&#xff0c;群晖安装&#xff0c;免不了踩些坑。 今天写篇博客&#xff0c;讲述一下群晖 Docker版qbittorrent 下载显示错误的解决方法&#xff0c;顺便记录一下配置&#xff0c;以便日后折腾可以参考。 直接…

几个国内可用的强大的GPT工具

前言&#xff1a; 人工智能发布至今&#xff0c;过去了九个多月&#xff0c;已经成为了我们不管是工作还是生活中一个重要的辅助工具&#xff0c;大大提升了效率&#xff0c;作为一个人工智能的自然语言处理工具&#xff0c;它给各大行业的提供了一个巨大的生产工具&#xff0c…

机器学习算法基础--逻辑回归

目录 1.数据收集及处理 2.数据提取及可视化 3.逻辑回归训练样本并且测试 4.绘制散点决策边界 逻辑回归的方法已经在数学建模里面讲过了&#xff0c;这里就不多讲了。 本篇我们主要是利用逻辑回归的方法来求解分类问题。 1.数据获取及处理 import pandas as pd from sklearn…

【深度学习框架格式转化】【CPU】Pytorch模型转ONNX模型格式流程详解【入门】

【深度学习框架格式转化】【GPU】Pytorch模型转ONNX模型格式流程详解【入门】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习框架格式转化】【GPU】Pytorch模型转ONNX模型格式流程详解【入门】前言PyTorch模型环境搭建(CPU)安装onn…

中国汽车供应商远赴德国,中国智驾方案能否远渡重洋?

作者|Amy 编辑|德新 今年的上海车展&#xff0c;中国智能汽车的进步有目共睹&#xff0c;吸引了大批外企高管和研发人员的关注&#xff0c;甚至引发了海外车企一系列的动作和调整。 而在刚刚结束的慕尼黑车展&#xff0c;中国车企及汽车供应链把「肌肉」秀到了现代汽车起源地…

大模型如何赋能智能客服

2022年&#xff0c;大模型技术的出色表现让人们瞩目。随着深度学习和大数据技术的发展&#xff0c;大模型在很多领域的应用已经成为可能。许多公司开始探索如何将大模型技术应用于自己的业务中&#xff0c;智能客服也不例外。 智能客服是现代企业中非常重要的一部分&#xff0…

Python 图形化界面基础篇:创建工具栏

Python 图形化界面基础篇&#xff1a;创建工具栏 引言 Tkinter 库简介步骤1&#xff1a;导入 Tkinter 模块步骤2&#xff1a;创建 Tkinter 窗口步骤3&#xff1a;创建工具栏步骤4&#xff1a;向工具栏添加工具按钮步骤5&#xff1a;处理工具按钮的点击事件步骤6&#xff1a;启动…