枚举简单例子
  1. /**
  2. * @author shuliangzhao
  3. * @Title: Color
  4. * @ProjectName design-parent
  5. * @Description: TODO
  6. * @date 2019/6/12 22:35
  7. */
  8. public enum Color {
  9. YELLOW,
  10. RED,
  11. BLUE,
  12. PURPLE,
  13. BLACK;
  14. }
  1. /**
  2. * @author shuliangzhao
  3. * @Title: ColorEnumTest
  4. * @ProjectName design-parent
  5. * @Description: TODO
  6. * @date 2019/6/12 22:37
  7. */
  8. public class ColorEnumTest {
  9. public static void main(String[] args) {
  10. Color color = Color.BLUE;
  11. switch (color) {
  12. case RED:
  13. System.out.println("红色");
  14. break;
  15. case BLUE:
  16. System.out.println("蓝色");
  17. break;
  18. case PURPLE:
  19. System.out.println("紫色");
  20. break;
  21. case BLACK:
  22. System.out.println("黑色");
  23. break;
  24. case YELLOW:
  25. System.out.println("黄色");
  26. break;
  27. default:
  28. System.out.println("蓝色");
  29. break;
  30. }
  31. }
  32. }

测试结果

 
image.png

Color枚举的本质就是一个类,编译器会自动为我们生成Color类,通过反编译得到该类如下:

  1. final class Color extends Enum {
  2. //编译器为我们添加的静态的values()方法
  3. public static Color[] values()
  4. {
  5. return (Color[])$VALUES.clone();
  6. }
  7. //编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法
  8. public static Color valueOf(String s)
  9. {
  10. return (Color)Enum.valueOf(com/sl/emun/Color, s);
  11. }
  12. //私有构造函数
  13. private Color(String s, int i)
  14. {
  15. super(s, i);
  16. }
  17. //前面定义的7种枚举实例
  18. public static final Color YELLOW;
  19. public static final Color RED;
  20. public static final Color BLUE;
  21. public static final Color PURPLE;
  22. public static final Color BLACK;
  23. private static final Color $VALUES[];
  24. static
  25. {
  26. //实例化枚举实例
  27. YELLOW = new Color("YELLOW", 0);
  28. RED = new Color("RED", 1);
  29. BLUE = new Color("BLUE", 2);
  30. PURPLE = new Color("PURPLE", 3);
  31. BLACK = new Color("BLACK", 4);
  32. $VALUES = (new Color[] {
  33. YELLOW, RED, BLUE, PURPLE, BLACK
  34. });
  35. }
  36. }

可以看出每个枚举类型颜色是该Color类的一个实例对象,该构成方式和单例模式有些类似,故可以用只有一个枚举类型的枚举作为单例模式,而且枚举的构造器由编译器管理安全性十分高,既可以防止反射破解也可以防止反序列破解。

EnumMap用法
  1. /**
  2. * @author shuliangzhao
  3. * @Title: EnumMapTest
  4. * @ProjectName design-parent
  5. * @Description: TODO
  6. * @date 2019/6/12 22:49
  7. */
  8. public class EnumMapTest {
  9. public static void main(String[] args) {
  10. EnumMap<Color,String> enumMap = new EnumMap(Color.class);
  11. enumMap.put(Color.BLACK,"黑色");
  12. enumMap.put(Color.BLUE,"蓝色");
  13. System.out.println(enumMap);
  14. System.out.println(enumMap.get(Color.BLUE));
  15. }
  16. }

运行结果

 
image.png

EnumMap put方法

  1. public V put(K key, V value) {
  2. typeCheck(key);
  3. int index = key.ordinal();
  4. Object oldValue = vals[index];
  5. vals[index] = maskNull(value);
  6. if (oldValue == null)
  7. size++;
  8. return unmaskNull(oldValue);
  9. }

首先调用typeCheck检查键的类型,如果类型不对,会抛出异常。类型正确的话,调用ordinal获取索引index,并将值value放入值数组vals[index]中。EnumMap允许值为null,为了区别null值与没有值,EnumMap将null值包装成了一个特殊的对象,有两个辅助方法用于null的打包和解包,打包方法为maskNull,解包方法为unmaskNull。

get方法

  1. public V get(Object key) {
  2. return (isValidKey(key) ?
  3. unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);
  4. }

键有效的话,通过ordinal方法取索引,然后直接在值数组vals里找。isValidKey的代码与typeCheck类似,但是返回boolean值而不是抛出异常。

以上就是EnumMap的基本实现原理,内部有两个数组,长度相同,一个表示所有的键,一个表示对应的值,值为null表示没有该键值对,键都有一个对应的索引,根据索引可直接访问和操作其键和值,效率很高。

EnumSet

EnumSet这是一个用来操作Enum的集合,是一个抽象类,它有两个继承类:JumboEnumSet和RegularEnumSet。在使用的时候,需要确定枚举类型。它的特点也是速度非常快,为什么速度很快呢?因为每次add的时候,每个枚举值只占一个长整型的一位。
EnumSet.noneOf()方法创建一个空的set

  1. public class EnumSetTest {
  2. public static void main(String[] args) {
  3. EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
  4. System.out.println(enumSet);
  5. enumSet.add(Color.BLUE);
  6. enumSet.add(Color.PURPLE);
  7. System.out.println(enumSet);
  8. }
  9. }

运行结果

 
image.png

EnumSet.allOf()方法创建一个满的set

  1. /**
  2. * @author shuliangzhao
  3. * @Title: EnumSetTest
  4. * @ProjectName design-parent
  5. * @Description: TODO
  6. * @date 2019/6/12 23:24
  7. */
  8. public class EnumSetTest {
  9. public static void main(String[] args) {
  10. /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
  11. System.out.println(enumSet);
  12. enumSet.add(Color.BLUE);
  13. enumSet.add(Color.PURPLE);
  14. System.out.println(enumSet);*/
  15. EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
  16. System.out.println(enumSet);
  17. }
  18. }

运行结果

 
image.png

EnumSet.range创建指定范围set

  1. public class EnumSetTest {
  2. public static void main(String[] args) {
  3. /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
  4. System.out.println(enumSet);
  5. enumSet.add(Color.BLUE);
  6. enumSet.add(Color.PURPLE);
  7. System.out.println(enumSet);
  8. EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
  9. System.out.println(enumSet);*/
  10. EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
  11. System.out.println(enumSet);
  12. }
  13. }
 
image.png

EnumSet.complementOf补集创建set

  1. public class EnumSetTest {
  2. public static void main(String[] args) {
  3. /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
  4. System.out.println(enumSet);
  5. enumSet.add(Color.BLUE);
  6. enumSet.add(Color.PURPLE);
  7. System.out.println(enumSet);
  8. EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
  9. System.out.println(enumSet);*/
  10. EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
  11. System.out.println(enumSet);
  12. EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet);
  13. System.out.println(enumSet1);
  14. }
  15. }

运行结果

 
image.png

EnumSet.copyOf复制创建set

  1. public class EnumSetTest {
  2. public static void main(String[] args) {
  3. /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
  4. System.out.println(enumSet);
  5. enumSet.add(Color.BLUE);
  6. enumSet.add(Color.PURPLE);
  7. System.out.println(enumSet);
  8. EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
  9. System.out.println(enumSet);
  10. EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
  11. System.out.println(enumSet);
  12. EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet);
  13. System.out.println(enumSet1);*/
  14. EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
  15. System.out.println(enumSet);
  16. EnumSet<Color> enumSet1 = EnumSet.copyOf(enumSet);
  17. System.out.println(enumSet1);
  18. }
  19. }

运行结果

 
image.png

EnumSet.copyOf复制创建集合

  1. public class EnumSetTest {
  2. public static void main(String[] args) {
  3. /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
  4. System.out.println(enumSet);
  5. enumSet.add(Color.BLUE);
  6. enumSet.add(Color.PURPLE);
  7. System.out.println(enumSet);
  8. EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
  9. System.out.println(enumSet);
  10. EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
  11. System.out.println(enumSet);
  12. EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet);
  13. System.out.println(enumSet1);
  14. EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);
  15. System.out.println(enumSet);
  16. EnumSet<Color> enumSet1 = EnumSet.copyOf(enumSet);
  17. System.out.println(enumSet1);*/
  18. List<Color> colors = new ArrayList<>();
  19. colors.add(Color.PURPLE);
  20. colors.add(Color.BLUE);
  21. colors.add(Color.BLUE);
  22. System.out.println(colors);
  23. EnumSet<Color> enumSet = EnumSet.copyOf(colors);
  24. System.out.println(enumSet);
  25. }
  26. }

运行结果

 
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. UVA - 10048 Audiophobia(Floyd求路径上最大值的最小)

    题目&分析: 思路: Floyd变形(见上述紫书分析),根据题目要求对应的改变判断条件来解题. 代码: #include <bits/stdc++.h> #define inf 0 ...

  2. journals in Fluid Dynamics

    annual review of fluid mechanicsjournal of fluid mechanicsphysics of fluidjournal of flow and struct ...

  3. 7-26 Windows消息队列

    7-26 Windows消息队列(25 分) 消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生,如点击鼠标.文字改变等,系统将把这个消息加到队列当中. ...

  4. 恶补数论(二) Baby-Step-Giant-Step 大步小步求离散模对数

    知识概述 好吧,我承认这是我初三寒假就听过的知识,然而我现在早就高一了(又是寒假,只不过我已经在省选了...) 额,这是求离散模对数的一种算法 也就是求满足方程a^x≡b(mod p)的最小的x(其中 ...

  5. mysql根据用户的邀请码查询该用户所有的上级

    SELECT T1.lvl AS 'level', T2.id AS 'id', T2.zid AS 'zid', T2.self_invite AS 'selfInvite', T2.invite_ ...

  6. lua 栈最后调用的函数,用于看调试信息

    lua_getinfo int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); 返回一个指定的函数或函数调用的信息. 当用于取 ...

  7. 【BZOJ2081】Beads(哈希表)

    题意: 翻转是指其中一段长度为k的子串全部翻转 n<=200000 a[i]<=n 思路:枚举k,直接哈希判充即可 时间复杂度是n/i求和,根据定理可得是O(n log n)级别的 单哈双 ...

  8. BZOJ(1) 1003 [ZJOI2006]物流运输

    1003: [ZJOI2006]物流运输 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 9404  Solved: 4087[Submit][Stat ...

  9. MyBatis3-实现单表数据的增删查改

    继续前一篇文章http://www.cnblogs.com/EasonJim/p/7050710.html所示的例子,返回的是单个实体,而接下来将进行列表的返回等操作: 一.查询列表 查询出列表,也就 ...

  10. 非常适合新手的jq/zepto源码分析08---ajax的封装

    1.现在看看对JSONP的封装 $.ajaxJSONP = function(options, deferred){ if (!('type' in options)) return $.ajax(o ...