枚举简单例子
/**
* @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. centos7在grub界面下更改root密码

    想要更改root的密码或者忘记了root的密码的时候可以在grub界面下更改root的密码. 百度了很多内容,更多方法都是适用于centos6及以前版本的,终于找到一个可以的. 1.开机后,在下图界面 ...

  2. 设置NODE_ENV=test环境变量

    之前开发时因为有内网测试环境和外网测试环境,再部署打包时总是切换两个域名,比较麻烦,所以最好能设置一个环境变量,来控制两个域名,于是做了如下配置: "scripts": { &qu ...

  3. 如何相互转换逗号分隔的字符串和List --https://blog.csdn.net/yywusuoweile/article/details/50315377

    如何相互转换逗号分隔的字符串和List ---https://blog.csdn.net/yywusuoweile/article/details/50315377 方法 2: 利用Guava的Joi ...

  4. 转载 - C - 枚举类型详解

    出处:http://www.cnblogs.com/JCSU/articles/1299051.html 注:以下全部代码的执行环境为VC++ 6.0 在程序中,可能需要为某些整数定义一个别名,我们可 ...

  5. 魔法猪学院(codevs 1835)

    题目描述 Description iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世 ...

  6. nyoj_79_拦截导弹_201403182040

    拦截导弹 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到 ...

  7. 使用Jsoup解析和操作HTML

    jsoup 简单介绍 jsoup 是一款 Java 的HTML 解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套很省力的API,可通过DOM.CSS以及类似于jQuery的操作方法来取 ...

  8. 【JAVA】两点经纬度直线距离的计算

    来自谷歌地图的计算公式: 通过JAVA的Math类各种方法调用.实现上述公式 private static double EARTH_RADIUS = 6378.137;// 单位千米 /** * 角 ...

  9. Chrome浏览器扩展开发系列之十四:本地消息机制Native messagin

    Chrome浏览器扩展开发系列之十四:本地消息机制Native messaging 2016-11-24 09:36 114人阅读 评论(0) 收藏 举报  分类: PPAPI(27)  通过将浏览器 ...

  10. poj 1741 楼教主男人八题之中的一个:树分治

    http://poj.org/problem? id=1741 Description Give a tree with n vertices,each edge has a length(posit ...