EnumSet
EnumSet is a generic container of Java enum type. Since Java has SortedSet, TreeSet, HashSet and other containers, why does it need an additional EnumSet<T>? The answer is that EnumSet has certain characteristics. For example, EnumSet is very fast. I won't list other features one by one, after all, the content of this article does not introduce the features of EnumSet.
Collection classes designed specifically for enumeration classes, all elements must be enumeration types
The set elements of EnumSet are ordered and are stored internally by bit vectors, so they occupy less memory and have high efficiency.
Null elements are not allowed
Source code
package java.util;import sun.misc.SharedSecrets;public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E> implements Cloneable, java.io.Serializable{ /** * Element type*/ final Class<E> elementType; /** * Store elements through array*/ final Enum[] universe; private static Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0]; EnumSet(Class<E> elementType, Enum[] universe) { this.elementType = elementType; this.universe = universe; } /** * Create an empty enum set and formulate its element type* @param elementType the class object of the element type for this enum * set * @throws NullPointerException if <tt>elementType</tt> is null */ 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) return new RegularEnumSet<>(elementType, universe); else return new JumboEnumSet<>(elementType, universe); } /** * Create an enum containing all elements in the specified element type set * * @param elementType the class object of the element type for this enum * set * @throws NullPointerException if <tt>elementType</tt> is null */ public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) { EnumSet<E> result = noneOf(elementType); result.addAll(); return result; } /** * Adds all of the elements from the appropriate enum type to this enum * set, which is empty prior to the call. */ abstract void addAll(); /** * Create an enum set with the same element type as the specified enum set * * @param s the enum set from which to initialize this enum set * @throws NullPointerException if <tt>s</tt> is null */ public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) { return s.clone(); } /** * Create an enum set from which to initialize this enum set * @throws IllegalArgumentException if <tt>c</tt> is not an * <tt>EnumSet</tt> instance and contains no elements * @throws NullPointerException if <tt>c</tt> is null */ 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; } } /** * Create an enum set from whose complement to initialize this enum set * @throws NullPointerException if <tt>s</tt> is null */ public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) { EnumSet<E> result = copyOf(s); result.complement(); return result; } /** * 1 element enumeration collection* * @param e the element that this set is to contain initially * @throws NullPointerException if <tt>e</tt> is null * @return an enum set initially containing the specified element */ public static <E extends Enum<E>> EnumSet<E> of(E e) { EnumSet<E> result = noneOf(e.getDeclaringClass()); result.add(e); return result; } /** * 2 element enumeration collection* * @param e1 an element that this set is to contain initially * @param e2 another element that this set is to contain initially * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ 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; } /** * 3 element enumeration collection* * @param e1 an element that this set is to contain initially * @param e2 another element that this set is to contain initially * @param e3 another element that this set is to contain initially * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ 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; } /** * 4 element enumeration set* @param e1 an element that this set is to contain initially * @param e2 another element that this set is to contain initially * @param e3 another element that this set is to contain initially * @param e4 another element that this set is to contain initially * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ 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; } /** * 5 element enumeration collection* * @param e1 an element that this set is to contain initially * @param e2 another element that this set is to contain initially * @param e3 another element that this set is to contain initially * @param e4 another element that this set is to contain initially * @param e5 another element that this set is to contain initially * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ 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; } /** * n * * @param first an element that the set is to contain initially * @param rest the remaining elements the set is to contain initially * @throws NullPointerException if any of the specified elements are null, * or if <tt>rest</tt> is null * @return an enum set initially containing the specified elements */ @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; } /** * Enumerated collection of elements in the range * @param from the first element in the range * @param to the last element in the range * @throws NullPointerException if {@code from} or {@code to} are null * @throws IllegalArgumentException if {@code from.compareTo(to) > 0} * @return an enum set initially containing all of the elements in the * range defined by the two specified endpoints */ 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; } /** * Adds the specified range to this enum set, which is empty prior * to the call. */ abstract void addRange(E from, E to); /** * Returns a copy of this set. * * @return a copy of this set */ public EnumSet<E> clone() { try { return (EnumSet<E>) super.clone(); } catch(CloneNotSupportedException e) { throw new AssertionError(e); } } /** * Complements the contents of this enum set. */ abstract void complement(); /** * Throws an exception if e is not of the correct type for this enum set. */ 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 { /** * The element type of this enum set. * * @serial */ private final Class<E> elementType; /** * The elements contained in this enum set. * * @serial */ private final Enum[] elements; SerializationProxy(EnumSet<E> set) { elementType = set.elementType; elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY); } 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"); }}Summarize
The above is all about reading the EnumSet abstract source code, and I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!