java集合(二)Set集合之EnumSet详解
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java集合(二)Set集合之EnumSet详解,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3086字,纯文字阅读大概需要5分钟。
内容图文
![java集合(二)Set集合之EnumSet详解](/upload/InfoBanner/zyjiaocheng/1290/2ff0b320855c4f7aa305246b5f352d47.jpg)
1.定义:
添加枚举类元素的专用集合类
2.与其他集合类区别:
EnumSet内部实现不使用常见的数据结构,比如数组(ArrayList),链表(LinkedList),哈系表(HashMap、Hashtable、HashSet),红黑树(TreeMap、TreeSet)而是使用位运算完成集合的基本操作
EnumSet是抽象类,只能通过静态工厂方法构造EnumSet对象,具体如下:
EnumSet<E> noneOf(Class<E> elementType):构造一个空的集合
EnumSet<E> allOf(Class<E> elementType):构造一个包含枚举类中所有枚举项的集合
EnumSet<E> of(E e):构造包含1个元素的集合
EnumSet<E> of(E e1, E e2):构造包含2个元素的集合
EnumSet<E> of(E e1, E e2, E e3):构造包含3个元素的集合
EnumSet<E> of(E e1, E e2, E e3, E e4):构造包含4个元素的集合
EnumSet<E> of(E e1, E e2, E e3, E e4, E e5):构造包含5个元素的集合
EnumSet<E> of(E first, E... rest):构造包含多个元素的集合(使用可变参数)
EnumSet<E> copyOf(EnumSet<E> s):构造包含参数中所有元素的集合
EnumSet<E> copyOf(Collection<E> c):构造包含参数中所有元素的集合
3.EnumSet作为集合类基本操作方法实现原理(位运算):
说明:
- 从EnumSet的
noneOf
可以看出,当枚举类中的枚举项少于64
时,返回的是RegularEnumSet类
(EnumSet的实现类
)对象,大于64,返回的是JumboEnumSet类对象,为了方便分析,后面同一使用RegularEnumSet类解释原理// EnumSet#noneOfpublicstatic <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) { Enum<?>[] universe = getUniverse(elementType); if (universe == null) thrownew ClassCastException(elementType + " not an enum"); if (universe.length <= 64) returnnew RegularEnumSet<>(elementType, universe); elsereturnnew JumboEnumSet<>(elementType, universe); }
- 测试用的枚举类
enum Color{ RED("RED"), BLUE("BLUE"), YELLOW("YELLOW"), BLACK("BLACK"); String name; Color(String name){ this.name = name; } @Override public String toString(){ returnthis.name; } }
3.1 add方法
public boolean add(E e) { typeCheck(e); long oldElements = elements; elements |= (1L << ((Enum<?>)e).ordinal()); return elements != oldElements; }
ordinal()为每个枚举项的序号,从0开始,按声明顺序排列,如[RED,BLUE,YELLOW,BLACK]对应[0,1,2,3];1L << ((Enum<?>)e).ordinal()(为了方便,这里称之为枚举值)则表示1*2^(e.ordinal()),Color.RED的ordianl()为0,对应枚举值为1*2^0=1,其实就是第ordinal()+1位(从右往左数,个位为第1位)为1其它位为0的十进制数,对应十进制数为00000001(这里假设是8bit,实际是long型32bit);
则每个枚举项表示如下:
枚举项 序号 1L << ((Enum<?>)e).ordinal() 枚举值
枚举项 | 序号 | 1L << ((Enum<?>)e).ordinal() | 枚举值 |
Color.RED | 0 | 00000001 | 1 |
Color.BLUE | 1 | 00000010 | 2 |
Color.YELLOW | 2 | 00000100 | 4 |
Color.BLACK | 3 | 00001000 | 8 |
elements |=
就是对添加的不同元素的枚举值进行求和,相同
元素相或
时保持不变
3.2 remove方法
public boolean remove(Object e) { if (e == null) returnfalse; Class<?> eClass = e.getClass(); if (eClass != elementType && eClass.getSuperclass() != elementType) returnfalse; long oldElements = elements; elements &= ~(1L << ((Enum<?>)e).ordinal()); return elements != oldElements; }
按照之前的枚举值相加
的想法,remove就是从总枚举值
中减去待删除元素的枚举值
,因为是位运算
,没有直接相减,使用位操作elements &= ~(1L << ((Enum<?>)e).ordinal());
完成相减操作
3.3 contains方法
public boolean contains(Object e) { if (e == null) returnfalse; Class<?> eClass = e.getClass(); if (eClass != elementType && eClass.getSuperclass() != elementType) returnfalse; return (elements & (1L << ((Enum<?>)e).ordinal())) != 0; }
contains方法就更好理解,每个枚举项的枚举值的值都不一样
,且相互之间
进行相与
操作为0
,使用总枚举值
与要查询的枚举项的枚举值
进行相与
操作,如果为0
,说明不存在
该枚举项,否则存在
原文:https://www.cnblogs.com/yuexiaoyun/p/12078048.html
内容总结
以上是互联网集市为您收集整理的java集合(二)Set集合之EnumSet详解全部内容,希望文章能够帮你解决java集合(二)Set集合之EnumSet详解所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。