介绍
EnumSet方便我们去处理enum类型的集合类型,该工具类实现Set接口,内部则使用位运算,在空间复杂度和时间复杂度上都有极大的优势,可以通过该类学习Java的位运算
批量初始化addRange
-1L >>> -n:生成一个n位个1的数- 然后左移
from位
1 2 3
| void addRange(E from, E to) { elements = (-1L >>> (from.ordinal() - to.ordinal() - 1)) << from.ordinal(); }
|
补充complement(反转)
1 2 3 4 5 6
| void complement() { if (universe.length != 0) { elements = ~elements; elements &= -1L >>> -universe.length; } }
|
大小size
- 计算1的个数,
Long.bitCount内部用了非常精巧的算法
1 2 3
| public int size() { return Long.bitCount(elements); }
|
是否为空isEmpty
1 2 3
| public boolean isEmpty() { return elements == 0; }
|
包含contains
1 2 3
| public boolean contains(Object e) { return (elements & (1L << e.ordinal())) != 0; }
|
添加add
1 2 3 4 5
| public boolean add(E e) { long oldElements = elements; elements |= (1L << ((Enum<?>)e).ordinal()); return elements != oldElements; }
|
移除remove
- 左移
e.ordinal()位取反,其他都是1,目标位置为0,然后取交
1 2 3 4 5
| public boolean remove(Object e) { long oldElements = elements; elements &= ~(1L << ((Enum<?>)e).ordinal()); return elements != oldElements; }
|
包含所有containsAll
- 如果类型不一致,则看c是否为空,如果是空也认为全部包含
- elements取反,得到该set“不存在的elements”,然后和目标的elements取并,如果不为0,说明目标elements存在“不存在的elements”,如果为0,说明不存在“不存在的elements”
1 2 3 4 5 6 7
| public boolean containsAll(Collection<?> c) { RegularEnumSet<?> es = (RegularEnumSet<?>)c; if (es.elementType != elementType) return es.isEmpty();
return (es.elements & ~elements) == 0; }
|
添加所有addAll
1 2 3 4 5 6 7 8
| public boolean addAll(Collection<? extends E> c) { RegularEnumSet<?> es = (RegularEnumSet<?>)c;
long oldElements = elements; elements |= es.elements;
return elements != oldElements; }
|
移除所有removeAll
- 将目标elements取反得到保留的,然后和现有的取并即可
1 2 3 4 5 6 7
| public boolean removeAll(Collection<?> c) { RegularEnumSet<?> es = (RegularEnumSet<?>)c;
long oldElements = elements; elements &= ~es.elements; return elements != oldElements; }
|
保留所有retainAll
1 2 3 4 5 6 7
| public boolean retainAll(Collection<?> c) { RegularEnumSet<?> es = (RegularEnumSet<?>)c;
long oldElements = elements; elements &= es.elements; return elements != oldElements; }
|
清除所有clear
1 2 3
| public void clear() { elements = 0; }
|
equals
- 类型不一样时比较elements的值是否都为0,
- 类型一样时直接比较elements的值
1 2 3 4 5 6
| public boolean equals(Object o) { RegularEnumSet<?> es = (RegularEnumSet<?>)o; if (es.elementType != elementType) return elements == 0 && es.elements == 0; return es.elements == elements; }
|