枚举详解之EnumSet、EnumMap用法
枚举简单例子
/**
* @author shuliangzhao
* @Title: Color
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/12 22:35
*/
public enum Color {
YELLOW,
RED,
BLUE,
PURPLE,
BLACK;
}
/**
* @author shuliangzhao
* @Title: ColorEnumTest
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/12 22:37
*/
public class ColorEnumTest {
public static void main(String[] args) {
Color color = Color.BLUE;
switch (color) {
case RED:
System.out.println("红色");
break;
case BLUE:
System.out.println("蓝色");
break;
case PURPLE:
System.out.println("紫色");
break;
case BLACK:
System.out.println("黑色");
break;
case YELLOW:
System.out.println("黄色");
break;
default:
System.out.println("蓝色");
break;
}
}
}
测试结果

Color枚举的本质就是一个类,编译器会自动为我们生成Color类,通过反编译得到该类如下:
final class Color extends Enum {
//编译器为我们添加的静态的values()方法
public static Color[] values()
{
return (Color[])$VALUES.clone();
}
//编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法
public static Color valueOf(String s)
{
return (Color)Enum.valueOf(com/sl/emun/Color, s);
}
//私有构造函数
private Color(String s, int i)
{
super(s, i);
}
//前面定义的7种枚举实例
public static final Color YELLOW;
public static final Color RED;
public static final Color BLUE;
public static final Color PURPLE;
public static final Color BLACK;
private static final Color $VALUES[];
static
{
//实例化枚举实例
YELLOW = new Color("YELLOW", 0);
RED = new Color("RED", 1);
BLUE = new Color("BLUE", 2);
PURPLE = new Color("PURPLE", 3);
BLACK = new Color("BLACK", 4);
$VALUES = (new Color[] {
YELLOW, RED, BLUE, PURPLE, BLACK
});
}
}
可以看出每个枚举类型颜色是该Color类的一个实例对象,该构成方式和单例模式有些类似,故可以用只有一个枚举类型的枚举作为单例模式,而且枚举的构造器由编译器管理安全性十分高,既可以防止反射破解也可以防止反序列破解。
EnumMap用法
/**
* @author shuliangzhao
* @Title: EnumMapTest
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/12 22:49
*/
public class EnumMapTest {
public static void main(String[] args) {
EnumMap<Color,String> enumMap = new EnumMap(Color.class);
enumMap.put(Color.BLACK,"黑色");
enumMap.put(Color.BLUE,"蓝色");
System.out.println(enumMap);
System.out.println(enumMap.get(Color.BLUE));
}
}
运行结果

EnumMap put方法
public V put(K key, V value) {
typeCheck(key);
int index = key.ordinal();
Object oldValue = vals[index];
vals[index] = maskNull(value);
if (oldValue == null)
size++;
return unmaskNull(oldValue);
}
首先调用typeCheck检查键的类型,如果类型不对,会抛出异常。类型正确的话,调用ordinal获取索引index,并将值value放入值数组vals[index]中。EnumMap允许值为null,为了区别null值与没有值,EnumMap将null值包装成了一个特殊的对象,有两个辅助方法用于null的打包和解包,打包方法为maskNull,解包方法为unmaskNull。
get方法
public V get(Object key) {
return (isValidKey(key) ?
unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);
}
键有效的话,通过ordinal方法取索引,然后直接在值数组vals里找。isValidKey的代码与typeCheck类似,但是返回boolean值而不是抛出异常。
以上就是EnumMap的基本实现原理,内部有两个数组,长度相同,一个表示所有的键,一个表示对应的值,值为null表示没有该键值对,键都有一个对应的索引,根据索引可直接访问和操作其键和值,效率很高。
EnumSet
EnumSet这是一个用来操作Enum的集合,是一个抽象类,它有两个继承类:JumboEnumSet和RegularEnumSet。在使用的时候,需要确定枚举类型。它的特点也是速度非常快,为什么速度很快呢?因为每次add的时候,每个枚举值只占一个长整型的一位。
EnumSet.noneOf()方法创建一个空的set
public class EnumSetTest {
public static void main(String[] args) {
EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
System.out.println(enumSet);
enumSet.add(Color.BLUE);
enumSet.add(Color.PURPLE);
System.out.println(enumSet);
}
}
运行结果

EnumSet.allOf()方法创建一个满的set
/**
* @author shuliangzhao
* @Title: EnumSetTest
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/12 23:24
*/
public class EnumSetTest {
public static void main(String[] args) {
/*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
System.out.println(enumSet);
enumSet.add(Color.BLUE);
enumSet.add(Color.PURPLE);
System.out.println(enumSet);*/
EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
System.out.println(enumSet);
}
}
运行结果

EnumSet.range创建指定范围set
public class EnumSetTest {
public static void main(String[] args) {
/*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
System.out.println(enumSet);
enumSet.add(Color.BLUE);
enumSet.add(Color.PURPLE);
System.out.println(enumSet);
EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
System.out.println(enumSet);*/
EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
System.out.println(enumSet);
}
}

EnumSet.complementOf补集创建set
public class EnumSetTest {
public static void main(String[] args) {
/*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
System.out.println(enumSet);
enumSet.add(Color.BLUE);
enumSet.add(Color.PURPLE);
System.out.println(enumSet);
EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
System.out.println(enumSet);*/
EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
System.out.println(enumSet);
EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet);
System.out.println(enumSet1);
}
}
运行结果

EnumSet.copyOf复制创建set
public class EnumSetTest {
public static void main(String[] args) {
/*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
System.out.println(enumSet);
enumSet.add(Color.BLUE);
enumSet.add(Color.PURPLE);
System.out.println(enumSet);
EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
System.out.println(enumSet);
EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
System.out.println(enumSet);
EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet);
System.out.println(enumSet1);*/
EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
System.out.println(enumSet);
EnumSet<Color> enumSet1 = EnumSet.copyOf(enumSet);
System.out.println(enumSet1);
}
}
运行结果

EnumSet.copyOf复制创建集合
public class EnumSetTest {
public static void main(String[] args) {
/*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
System.out.println(enumSet);
enumSet.add(Color.BLUE);
enumSet.add(Color.PURPLE);
System.out.println(enumSet);
EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
System.out.println(enumSet);
EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
System.out.println(enumSet);
EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet);
System.out.println(enumSet1);
EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
System.out.println(enumSet);
EnumSet<Color> enumSet1 = EnumSet.copyOf(enumSet);
System.out.println(enumSet1);*/
List<Color> colors = new ArrayList<>();
colors.add(Color.PURPLE);
colors.add(Color.BLUE);
colors.add(Color.BLUE);
System.out.println(colors);
EnumSet<Color> enumSet = EnumSet.copyOf(colors);
System.out.println(enumSet);
}
}
运行结果

注意:通过结果可以看出ArrayList内放置的元素可以重复,而EnumSet内放置的元素不重复。
枚举详解之EnumSet、EnumMap用法的更多相关文章
- linux 详解useradd 命令基本用法
linux 详解useradd 命令基本用法 时间:2019-03-24 本文章向大家介绍linux 详解useradd 命令基本用法,主要包括linux 详解useradd 命令基本用法使用实例.应 ...
- [转] - JAR文件包及jar命令详解 ( MANIFEST.MF的用法 )
常常在网上看到有人询问:如何把 java 程序编译成 .exe 文件.通常回答只有两种,一种是制作一个可执行的 JAR 文件包,然后就可以像. chm 文档一样双击运行了:而另一种是使用 JET 来进 ...
- 详解python中@的用法
python中@的用法 @是一个装饰器,针对函数,起调用传参的作用. 有修饰和被修饰的区别,‘@function'作为一个装饰器,用来修饰紧跟着的函数(可以是另一个装饰器,也可以是函数定义). 代码1 ...
- yield关键字详解与三种用法
本篇文章比较硬核, 适合有一定Python基础的读者阅读, 如果您对Python还不甚了解可以先关注我哦, 我会持续更新Python技术文章 yield详解 yield与return相同每次调用都会返 ...
- java基础篇---枚举详解
在JDK1.5之前,JAVA可以有两种方式定义新类型:类和接口,对于大部分面向对象编程,有这两种似乎就足够了,但是在一些特殊情况就不合适.例如:想要定义一个Color类,它只能有Red,Green,B ...
- nmap详解之原理与用法
前言 nmap是一款开源免费的网络发现(Network Discovery)和安全审计(Security Auditing)工具.软件名字Nmap是Network Mapper的简称.Nmap最初是由 ...
- 实用的PHP功能详解(一)_php glob()用法
一.使用glob()查找文件 大部分PHP函数的函数名从字面上都可以理解其用途,但是当你看到 glob() 的时候,你也许并不知道这是用来做什么的,其实glob()和scandir() 一样,可以用来 ...
- C# 控件双缓冲控制 ControlStyles 枚举详解
ControlStyles 枚举 .NET Framework 4 指定控件的样式和行为. 此枚举有一个 FlagsAttribute 特性,通过该特性可使其成员值按位组合. 命名空间: Sy ...
- Java 枚举详解
为什么要用枚举 在博客系统中,一篇文章有且可能有这几种状态, 数据库中article文章表中state字段存储数值,表示其状态: 0(已发表Published) 1(草稿Draft) 2(撤回撤回(D ...
随机推荐
- Linux 中设置 MySQL 字符集为 UTF-8
(1)查看 MySQL 字符集 登录 mysql:mysql -u root -p 查询 mysql 字符集:mysql> show variables like 'chara%'; 说明:将 ...
- 网络配置:IP+NETMASK+GATEWAY+DNS
1. IP IP地址(英语:Internet Protocol Address)是一种在Internet上的给主机编址的方式,也称为网际协议地址.常见的IP地址,分为IPv4与IPv6两大类. IP ...
- linux tload-显示系统负载状况
推荐:更多linux 性能监测与优化 关注:linux命令大全 tload命令以图形化的方式输出当前系统的平均负载到指定的终端.假设不给予终端机编号,则会在执行tload指令的终端机显示负载情形. 语 ...
- #if 0的意义和好处
在调试中经常遇到,写好的程序,需要调试相反的两方面,如:有两款单片机的程序,分别对应着不同的硬件引脚,我们把代码都写上了,但是不能同时让他们起效,通常的办法是/**/屏蔽一些段落,但是调试起来很麻烦. ...
- Dubbo 是一个分布式服务框架
Dubbo 是一个分布式服务框架-----http://www.cnblogs.com/chanshuyi/p/5144288.html
- 1874 Bellman-ford算法 队列优化过的 用于稀疏图,有负权的图
#include<stdio.h> #include<algorithm> #include<iostream> #include<queue> usi ...
- SCOI2010第一场
NOI2010全国青少年信息学奥林匹克竞赛 四川代表队选拔赛 第一场 题目名称 幸运数字 游戏 股票交易 英文代号 luckynumber game trade 时限 2秒 2秒 2秒 输入文件 lu ...
- Bellman_ford 算法 Currency Exchange POJ1860
Bellman_ford算法用于寻找正环或者负环! 算法导论: 24.1 The Bellman-Ford algorithm The Bellman-Ford algorithm solves th ...
- docker: 定时检查docker container的运行状态并发邮件报警
首先创建一个发送邮件的bash脚本 - send_mail.sh: #!/bin/bash curl -s --user 'api:key-xxxxxxxxxxxxx' \ https://api.m ...
- 深入学习理解java-ThreadLocal
导读 首先,ThreadLocal 不是用来解决共享对象的多线程訪问问题的,普通情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其它线程是不须要訪问的,也訪问不到 ...