枚举详解之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 ...
随机推荐
- 「 RQNOJ PID204 」 特种部队
解题思路 看了一下题解,感觉题解貌似有些错误.所以把我的见解放在这里,希望路过的大佬可以帮忙解释一下 QAQ 就是这里的更新 $dp[i-1][i]$ 和 $dp[i][i-1]$ 的时候,之前博主说 ...
- UVA-127 "Accordian" Patience(模拟)
题目: 把52张牌从左到右排好,每张牌自成一个牌堆.当某张牌与它左边那张牌或者左边第三张牌匹配时(花色或者点数相同)时,就把这张牌移到那张牌上面. 移动之后还要查看是否可以进行其他移动.只有位于牌堆顶 ...
- Linux 中设置 MySQL 字符集为 UTF-8
(1)查看 MySQL 字符集 登录 mysql:mysql -u root -p 查询 mysql 字符集:mysql> show variables like 'chara%'; 说明:将 ...
- LINUX-文件系统分析
badblocks -v /dev/hda1 检查磁盘hda1上的坏磁块 fsck /dev/hda1 修复/检查hda1磁盘上linux文件系统的完整性 fsck.ext2 /dev/hda1 修 ...
- 关于ajax跨域请求API数据的一些问题
一般来说我们使用jquery的ajax来跨域请求API数据的时候每次请求,就只能请求一组数据,而且当我们再次点击发送ajax请求的时候,新请求的数据会覆盖掉原来的数据,那么如何每次在请求的数据的时候, ...
- 解决CUDA程序的黑屏恢复问题
本文引用自 http://blog.163.com/yuhua_kui/blog/static/9679964420146183211348/ 问题描述: 在运行CUDA程序时,出现黑屏,过一会儿 ...
- 【Codeforces 9989C】A Mist of Florescence
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 四个大角 然后每个大角里面包着一些其他颜色的就好 [代码] #include <bits/stdc++.h> using name ...
- 【Codeforces 598D】Igor In the Museum
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 同一个联通块里面答案都一样. 把每个联通块的答案都算出来 然后赋值就好 [代码] #include <bits/stdc++.h> ...
- Leetcode 90.子集
子集 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: [1,2,2] 输出: [ [2], [1], [1,2,2], ...
- 洛谷—— P2919 [USACO08NOV]守护农场Guarding the Farm
https://www.luogu.org/problem/show?pid=2919 题目描述 The farm has many hills upon which Farmer John woul ...