枚举简单例子
/**
* @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;
}
} }

测试结果

 
image.png

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));
}
}

运行结果

 
image.png

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);
}
}

运行结果

 
image.png

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);
}
}

运行结果

 
image.png

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);
}
}
 
image.png

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);
}
}

运行结果

 
image.png

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);
}
}

运行结果

 
image.png

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);
}
}

运行结果

 
image.png

注意:通过结果可以看出ArrayList内放置的元素可以重复,而EnumSet内放置的元素不重复。

枚举详解之EnumSet、EnumMap用法的更多相关文章

  1. linux 详解useradd 命令基本用法

    linux 详解useradd 命令基本用法 时间:2019-03-24 本文章向大家介绍linux 详解useradd 命令基本用法,主要包括linux 详解useradd 命令基本用法使用实例.应 ...

  2. [转] - JAR文件包及jar命令详解 ( MANIFEST.MF的用法 )

    常常在网上看到有人询问:如何把 java 程序编译成 .exe 文件.通常回答只有两种,一种是制作一个可执行的 JAR 文件包,然后就可以像. chm 文档一样双击运行了:而另一种是使用 JET 来进 ...

  3. 详解python中@的用法

    python中@的用法 @是一个装饰器,针对函数,起调用传参的作用. 有修饰和被修饰的区别,‘@function'作为一个装饰器,用来修饰紧跟着的函数(可以是另一个装饰器,也可以是函数定义). 代码1 ...

  4. yield关键字详解与三种用法

    本篇文章比较硬核, 适合有一定Python基础的读者阅读, 如果您对Python还不甚了解可以先关注我哦, 我会持续更新Python技术文章 yield详解 yield与return相同每次调用都会返 ...

  5. java基础篇---枚举详解

    在JDK1.5之前,JAVA可以有两种方式定义新类型:类和接口,对于大部分面向对象编程,有这两种似乎就足够了,但是在一些特殊情况就不合适.例如:想要定义一个Color类,它只能有Red,Green,B ...

  6. nmap详解之原理与用法

    前言 nmap是一款开源免费的网络发现(Network Discovery)和安全审计(Security Auditing)工具.软件名字Nmap是Network Mapper的简称.Nmap最初是由 ...

  7. 实用的PHP功能详解(一)_php glob()用法

    一.使用glob()查找文件 大部分PHP函数的函数名从字面上都可以理解其用途,但是当你看到 glob() 的时候,你也许并不知道这是用来做什么的,其实glob()和scandir() 一样,可以用来 ...

  8. C# 控件双缓冲控制 ControlStyles 枚举详解

    ControlStyles 枚举 .NET Framework 4    指定控件的样式和行为. 此枚举有一个 FlagsAttribute 特性,通过该特性可使其成员值按位组合. 命名空间:  Sy ...

  9. Java 枚举详解

    为什么要用枚举 在博客系统中,一篇文章有且可能有这几种状态, 数据库中article文章表中state字段存储数值,表示其状态: 0(已发表Published) 1(草稿Draft) 2(撤回撤回(D ...

随机推荐

  1. Mybatis中and和or的细节处理

    当一条SQL中既有条件查又有模糊查的时候,偶尔会遇到这样的and拼接问题.参考如下代码: <select id="listSelectAllBusiness"> sel ...

  2. python_ 学习笔记(hello world)

    python中的循环语句 循环语句均可以尾随一个else语句块,该块再条件为false后执行一次 如果使用break跳出则不执行. for it in [1,2,3,4]: print(it,end= ...

  3. 常用Linux命令_20190211

    1.创建文件夹:mkdir 文件夹名称 2.查看IP地址信息:ipconfig -a 3.查看内存使用情况:free -m 4.查看CPU使用情况:top 5.查看磁盘使用情况:df -a/-h 6. ...

  4. 第一章 Linux命令行简介

    1 Linux系统命令操作语法的格式 命令_[参数选项]_[文件或路径]    其中 _ 至少一个空格    如:rm -f /etc/hosts    其中/etc/hosts完整路径不带空格   ...

  5. xe的debug怪现象

    死活有问题,而且不能重新编译生成文件. 查网上说明:在删除项目xxx.dproj文件后,然后打开dpk文件,会自动生成.dproj文件,再然后一切OK. 的确如此,但莫名其妙.

  6. Win32编程API 基础篇 -- 3.消息处理 根据英文教程翻译

    消息处理 例子:窗口点击 好的,现在我们已经得到一个窗口了,但我们什么也做不了除了DefWindowProc()允许窗口大小被调整,最大最小化等...这不是很激动人心啊 在接下来的一小节中我将向你展示 ...

  7. - > 网络流(草地排水)

    网络流(Dinic(模板)) Drainage Ditches Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  8. Nginx 重写规则指南

    作者:运维生存时间 - 默北 链接:www.ttlsa.com/nginx/nginx-rewriting-rules-guide/ 当运维遇到要重写情况时,往往是要程序员把重写规则写好后,发给你,你 ...

  9. 关于System.Convert那些事

    关于System.Convert那些事 前言 不知咋的,今天腰疼的不行,疼的站不起来了,今下午突然就疼起来了,唉,这是身体要垮了的节奏啊,再加上自己的VAX试用期到了,弄了半天也不行,烦. 正文 看到 ...

  10. CF 445B(DZY Loves Chemistry-求连通块)

    B. DZY Loves Chemistry time limit per test 1 second memory limit per test 256 megabytes input standa ...