EnumSet

原创 2018年04月14日 22:10:47
@SuppressWarnings("serial") // No serialVersionUID due to usage of
                            // serial proxy pattern
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
    implements Cloneable, java.io.Serializable
{
    final Class<E> elementType;

    /**
     * All of the values comprising T.  (Cached for performance.)
     */
    final Enum<?>[] universe;

    EnumSet(Class<E>elementType, Enum<?>[] universe) {
        this.elementType = elementType;
        this.universe    = universe;
    }

    public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
        Enum<?>[] universe = getUniverse(elementType);
        if (universe == null)
            throw new ClassCastException(elementType + " not an enum");
		//工厂
        if (universe.length <= 64)
			//long存储
            return new RegularEnumSet<>(elementType, universe);
        else
			//long[]存储
            return new JumboEnumSet<>(elementType, universe);
    }

    public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
        EnumSet<E> result = noneOf(elementType);
        result.addAll();
        return result;
    }

    abstract void addAll();

    public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
        return s.clone();
    }

    public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
        if (c instanceof EnumSet) {
            return ((EnumSet<E>)c).clone();
        } else {
            if (c.isEmpty())
                throw new IllegalArgumentException("Collection is empty");
            Iterator<E> i = c.iterator();
            E first = i.next();
            EnumSet<E> result = EnumSet.of(first);
            while (i.hasNext())
                result.add(i.next());
            return result;
        }
    }

    public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
        EnumSet<E> result = copyOf(s);
        result.complement();
        return result;
    }

    public static <E extends Enum<E>> EnumSet<E> of(E e) {
        EnumSet<E> result = noneOf(e.getDeclaringClass());
        result.add(e);
        return result;
    }

    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
        result.add(e1);
        result.add(e2);
        return result;
    }

    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
        result.add(e1);
        result.add(e2);
        result.add(e3);
        return result;
    }
 
    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
        result.add(e1);
        result.add(e2);
        result.add(e3);
        result.add(e4);
        return result;
    }

    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4,
                                                    E e5)
    {
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
        result.add(e1);
        result.add(e2);
        result.add(e3);
        result.add(e4);
        result.add(e5);
        return result;
    }

    @SafeVarargs
    public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
        EnumSet<E> result = noneOf(first.getDeclaringClass());
        result.add(first);
        for (E e : rest)
            result.add(e);
        return result;
    }

    //包含to
    public static <E extends Enum<E>> EnumSet<E> range(E from, E to) {
        if (from.compareTo(to) > 0)
            throw new IllegalArgumentException(from + " > " + to);
        EnumSet<E> result = noneOf(from.getDeclaringClass());
        result.addRange(from, to);
        return result;
    }
	
    abstract void addRange(E from, E to);

    @SuppressWarnings("unchecked")
    public EnumSet<E> clone() {
        try {
            return (EnumSet<E>) super.clone();
        } catch(CloneNotSupportedException e) {
            throw new AssertionError(e);
        }
    }

    abstract void complement();
    final void typeCheck(E e) {
        Class<?> eClass = e.getClass();
        if (eClass != elementType && eClass.getSuperclass() != elementType)
            throw new ClassCastException(eClass + " != " + elementType);
    }

    /**
     * Returns all of the values comprising E.
     * The result is uncloned, cached, and shared by all callers.
     */
    private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {
        return SharedSecrets.getJavaLangAccess()
                                        .getEnumConstantsShared(elementType);
    }

    /**
     * This class is used to serialize all EnumSet instances, regardless of
     * implementation type.  It captures their "logical contents" and they
     * are reconstructed using public static factories.  This is necessary
     * to ensure that the existence of a particular implementation type is
     * an implementation detail.
     *
     * @serial include
     */
    private static class SerializationProxy <E extends Enum<E>>
        implements java.io.Serializable
    {

        private static final Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];

        private final Class<E> elementType;

        private final Enum<?>[] elements;

        SerializationProxy(EnumSet<E> set) {
            elementType = set.elementType;
            elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
        }

        // instead of cast to E, we should perhaps use elementType.cast()
        // to avoid injection of forged stream, but it will slow the implementation
        @SuppressWarnings("unchecked")
        private Object readResolve() {
            EnumSet<E> result = EnumSet.noneOf(elementType);
            for (Enum<?> e : elements)
                result.add((E)e);
            return result;
        }

        private static final long serialVersionUID = 362491234563181265L;
    }

    Object writeReplace() {
        return new SerializationProxy<>(this);
    }

    // readObject method for the serialization proxy pattern
    // See Effective Java, Second Ed., Item 78.
    private void readObject(java.io.ObjectInputStream stream)
        throws java.io.InvalidObjectException {
        throw new java.io.InvalidObjectException("Proxy required");
    }
}

EnumSet类

package 集合类.Set类; /** * Set不允许重复数据 */ /** * 这个类是1.5开始有的, * 目前个人使用量几乎为零,很少使用 * 其使用方式和普通的Set没有区别...
  • randomnet
  • randomnet
  • 2013-01-03 11:16:26
  • 7501

Java集合之EnumSet

EnumSetEnumSet 是一个专为枚举设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式地指定。 EnumSet的集合元素也是有序的...
  • wxc880924
  • wxc880924
  • 2016-09-22 17:12:46
  • 1820

用EnumSet代替位域。

博文中的内容来源《Effective Java Second Edition》这一本书,感激不尽。
  • en_joker
  • en_joker
  • 2017-11-30 20:56:39
  • 88

[疯狂Java]集合:EnumSet、各Set性能分析(选择)

1. EnumSet——专门存放枚举类型元素的Set:     1) EnumSet只能存放一种枚举类型的元素,具体存放什么枚举类型的元素可以通过两种方法指定,一种是显式,一种是隐式;     2) ...
  • Lirx_Tech
  • Lirx_Tech
  • 2016-05-27 15:41:02
  • 1475

Java 之EnumSet与EnumMap

Java 之EnumSet与EnumMap EnumSet是Java枚举类型的泛型容器,Java既然有了SortedSet、TreeSet、HashSet等容器,为何还要多一个EnumSet呢?答案...
  • mawming
  • mawming
  • 2016-09-05 10:54:46
  • 856

EnumSet抽象类源码解析

EnumSet 专门为枚举类设计的集合类,所有元素必须是枚举类型 EnumSet的集合元素是有序的,内部以位向量的形成存储,因此占用内存小,效率高 不允许加入null元素 源码 package...
  • qunxingvip
  • qunxingvip
  • 2016-07-16 16:39:48
  • 1004

EffectiveJava(32) -- 用EnumSet代替位域

在进入正题之前,首先让我们来了解一下什么是位域位域是指信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。 例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。 为了节...
  • JacXuan
  • JacXuan
  • 2017-03-18 23:09:27
  • 8422

(32):用EnumSet代替位域

位域:就是用int枚举模式,将2的不同倍数赋予每个常量,这种表示法让你用OR位运算将几个常量合并到一个集合中(int值),称作位域(bit field)。 位域的写法就不介绍了,总之这种写法缺陷比较...
  • ahui2333
  • ahui2333
  • 2017-04-14 10:54:21
  • 267

EnumSet源码分析

核心:long(long数组) 和 位运算             其存储结构elements并未直接存枚举本身,而是位标识,枚举存于elementType中的enumConstants中. 1、...
  • u010887744
  • u010887744
  • 2016-03-09 13:48:12
  • 12239

enumset和enummap使用示例

http://hi.baidu.com/lck0502/item/2ddd2b32e6dcfbf4a884287f EnumMap 和 EnumSet java.util 程序包中...
  • mldxs
  • mldxs
  • 2013-06-08 22:48:57
  • 2740
收藏助手
不良信息举报
您举报文章:EnumSet
举报原因:
原因补充:

(最多只允许输入30个字)