Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/util/EnumSet.java
38829 views
/*1* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.util;2627import sun.misc.SharedSecrets;2829/**30* A specialized {@link Set} implementation for use with enum types. All of31* the elements in an enum set must come from a single enum type that is32* specified, explicitly or implicitly, when the set is created. Enum sets33* are represented internally as bit vectors. This representation is34* extremely compact and efficient. The space and time performance of this35* class should be good enough to allow its use as a high-quality, typesafe36* alternative to traditional <tt>int</tt>-based "bit flags." Even bulk37* operations (such as <tt>containsAll</tt> and <tt>retainAll</tt>) should38* run very quickly if their argument is also an enum set.39*40* <p>The iterator returned by the <tt>iterator</tt> method traverses the41* elements in their <i>natural order</i> (the order in which the enum42* constants are declared). The returned iterator is <i>weakly43* consistent</i>: it will never throw {@link ConcurrentModificationException}44* and it may or may not show the effects of any modifications to the set that45* occur while the iteration is in progress.46*47* <p>Null elements are not permitted. Attempts to insert a null element48* will throw {@link NullPointerException}. Attempts to test for the49* presence of a null element or to remove one will, however, function50* properly.51*52* <P>Like most collection implementations, <tt>EnumSet</tt> is not53* synchronized. If multiple threads access an enum set concurrently, and at54* least one of the threads modifies the set, it should be synchronized55* externally. This is typically accomplished by synchronizing on some56* object that naturally encapsulates the enum set. If no such object exists,57* the set should be "wrapped" using the {@link Collections#synchronizedSet}58* method. This is best done at creation time, to prevent accidental59* unsynchronized access:60*61* <pre>62* Set<MyEnum> s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));63* </pre>64*65* <p>Implementation note: All basic operations execute in constant time.66* They are likely (though not guaranteed) to be much faster than their67* {@link HashSet} counterparts. Even bulk operations execute in68* constant time if their argument is also an enum set.69*70* <p>This class is a member of the71* <a href="{@docRoot}/../technotes/guides/collections/index.html">72* Java Collections Framework</a>.73*74* @author Josh Bloch75* @since 1.576* @see EnumMap77* @serial exclude78*/79public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>80implements Cloneable, java.io.Serializable81{82/**83* The class of all the elements of this set.84*/85final Class<E> elementType;8687/**88* All of the values comprising T. (Cached for performance.)89*/90final Enum<?>[] universe;9192private static Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];9394EnumSet(Class<E>elementType, Enum<?>[] universe) {95this.elementType = elementType;96this.universe = universe;97}9899/**100* Creates an empty enum set with the specified element type.101*102* @param <E> The class of the elements in the set103* @param elementType the class object of the element type for this enum104* set105* @return An empty enum set of the specified type.106* @throws NullPointerException if <tt>elementType</tt> is null107*/108public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {109Enum<?>[] universe = getUniverse(elementType);110if (universe == null)111throw new ClassCastException(elementType + " not an enum");112113if (universe.length <= 64)114return new RegularEnumSet<>(elementType, universe);115else116return new JumboEnumSet<>(elementType, universe);117}118119/**120* Creates an enum set containing all of the elements in the specified121* element type.122*123* @param <E> The class of the elements in the set124* @param elementType the class object of the element type for this enum125* set126* @return An enum set containing all the elements in the specified type.127* @throws NullPointerException if <tt>elementType</tt> is null128*/129public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {130EnumSet<E> result = noneOf(elementType);131result.addAll();132return result;133}134135/**136* Adds all of the elements from the appropriate enum type to this enum137* set, which is empty prior to the call.138*/139abstract void addAll();140141/**142* Creates an enum set with the same element type as the specified enum143* set, initially containing the same elements (if any).144*145* @param <E> The class of the elements in the set146* @param s the enum set from which to initialize this enum set147* @return A copy of the specified enum set.148* @throws NullPointerException if <tt>s</tt> is null149*/150public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {151return s.clone();152}153154/**155* Creates an enum set initialized from the specified collection. If156* the specified collection is an <tt>EnumSet</tt> instance, this static157* factory method behaves identically to {@link #copyOf(EnumSet)}.158* Otherwise, the specified collection must contain at least one element159* (in order to determine the new enum set's element type).160*161* @param <E> The class of the elements in the collection162* @param c the collection from which to initialize this enum set163* @return An enum set initialized from the given collection.164* @throws IllegalArgumentException if <tt>c</tt> is not an165* <tt>EnumSet</tt> instance and contains no elements166* @throws NullPointerException if <tt>c</tt> is null167*/168public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {169if (c instanceof EnumSet) {170return ((EnumSet<E>)c).clone();171} else {172if (c.isEmpty())173throw new IllegalArgumentException("Collection is empty");174Iterator<E> i = c.iterator();175E first = i.next();176EnumSet<E> result = EnumSet.of(first);177while (i.hasNext())178result.add(i.next());179return result;180}181}182183/**184* Creates an enum set with the same element type as the specified enum185* set, initially containing all the elements of this type that are186* <i>not</i> contained in the specified set.187*188* @param <E> The class of the elements in the enum set189* @param s the enum set from whose complement to initialize this enum set190* @return The complement of the specified set in this set191* @throws NullPointerException if <tt>s</tt> is null192*/193public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {194EnumSet<E> result = copyOf(s);195result.complement();196return result;197}198199/**200* Creates an enum set initially containing the specified element.201*202* Overloadings of this method exist to initialize an enum set with203* one through five elements. A sixth overloading is provided that204* uses the varargs feature. This overloading may be used to create205* an enum set initially containing an arbitrary number of elements, but206* is likely to run slower than the overloadings that do not use varargs.207*208* @param <E> The class of the specified element and of the set209* @param e the element that this set is to contain initially210* @throws NullPointerException if <tt>e</tt> is null211* @return an enum set initially containing the specified element212*/213public static <E extends Enum<E>> EnumSet<E> of(E e) {214EnumSet<E> result = noneOf(e.getDeclaringClass());215result.add(e);216return result;217}218219/**220* Creates an enum set initially containing the specified elements.221*222* Overloadings of this method exist to initialize an enum set with223* one through five elements. A sixth overloading is provided that224* uses the varargs feature. This overloading may be used to create225* an enum set initially containing an arbitrary number of elements, but226* is likely to run slower than the overloadings that do not use varargs.227*228* @param <E> The class of the parameter elements and of the set229* @param e1 an element that this set is to contain initially230* @param e2 another element that this set is to contain initially231* @throws NullPointerException if any parameters are null232* @return an enum set initially containing the specified elements233*/234public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {235EnumSet<E> result = noneOf(e1.getDeclaringClass());236result.add(e1);237result.add(e2);238return result;239}240241/**242* Creates an enum set initially containing the specified elements.243*244* Overloadings of this method exist to initialize an enum set with245* one through five elements. A sixth overloading is provided that246* uses the varargs feature. This overloading may be used to create247* an enum set initially containing an arbitrary number of elements, but248* is likely to run slower than the overloadings that do not use varargs.249*250* @param <E> The class of the parameter elements and of the set251* @param e1 an element that this set is to contain initially252* @param e2 another element that this set is to contain initially253* @param e3 another element that this set is to contain initially254* @throws NullPointerException if any parameters are null255* @return an enum set initially containing the specified elements256*/257public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {258EnumSet<E> result = noneOf(e1.getDeclaringClass());259result.add(e1);260result.add(e2);261result.add(e3);262return result;263}264265/**266* Creates an enum set initially containing the specified elements.267*268* Overloadings of this method exist to initialize an enum set with269* one through five elements. A sixth overloading is provided that270* uses the varargs feature. This overloading may be used to create271* an enum set initially containing an arbitrary number of elements, but272* is likely to run slower than the overloadings that do not use varargs.273*274* @param <E> The class of the parameter elements and of the set275* @param e1 an element that this set is to contain initially276* @param e2 another element that this set is to contain initially277* @param e3 another element that this set is to contain initially278* @param e4 another element that this set is to contain initially279* @throws NullPointerException if any parameters are null280* @return an enum set initially containing the specified elements281*/282public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {283EnumSet<E> result = noneOf(e1.getDeclaringClass());284result.add(e1);285result.add(e2);286result.add(e3);287result.add(e4);288return result;289}290291/**292* Creates an enum set initially containing the specified elements.293*294* Overloadings of this method exist to initialize an enum set with295* one through five elements. A sixth overloading is provided that296* uses the varargs feature. This overloading may be used to create297* an enum set initially containing an arbitrary number of elements, but298* is likely to run slower than the overloadings that do not use varargs.299*300* @param <E> The class of the parameter elements and of the set301* @param e1 an element that this set is to contain initially302* @param e2 another element that this set is to contain initially303* @param e3 another element that this set is to contain initially304* @param e4 another element that this set is to contain initially305* @param e5 another element that this set is to contain initially306* @throws NullPointerException if any parameters are null307* @return an enum set initially containing the specified elements308*/309public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4,310E e5)311{312EnumSet<E> result = noneOf(e1.getDeclaringClass());313result.add(e1);314result.add(e2);315result.add(e3);316result.add(e4);317result.add(e5);318return result;319}320321/**322* Creates an enum set initially containing the specified elements.323* This factory, whose parameter list uses the varargs feature, may324* be used to create an enum set initially containing an arbitrary325* number of elements, but it is likely to run slower than the overloadings326* that do not use varargs.327*328* @param <E> The class of the parameter elements and of the set329* @param first an element that the set is to contain initially330* @param rest the remaining elements the set is to contain initially331* @throws NullPointerException if any of the specified elements are null,332* or if <tt>rest</tt> is null333* @return an enum set initially containing the specified elements334*/335@SafeVarargs336public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {337EnumSet<E> result = noneOf(first.getDeclaringClass());338result.add(first);339for (E e : rest)340result.add(e);341return result;342}343344/**345* Creates an enum set initially containing all of the elements in the346* range defined by the two specified endpoints. The returned set will347* contain the endpoints themselves, which may be identical but must not348* be out of order.349*350* @param <E> The class of the parameter elements and of the set351* @param from the first element in the range352* @param to the last element in the range353* @throws NullPointerException if {@code from} or {@code to} are null354* @throws IllegalArgumentException if {@code from.compareTo(to) > 0}355* @return an enum set initially containing all of the elements in the356* range defined by the two specified endpoints357*/358public static <E extends Enum<E>> EnumSet<E> range(E from, E to) {359if (from.compareTo(to) > 0)360throw new IllegalArgumentException(from + " > " + to);361EnumSet<E> result = noneOf(from.getDeclaringClass());362result.addRange(from, to);363return result;364}365366/**367* Adds the specified range to this enum set, which is empty prior368* to the call.369*/370abstract void addRange(E from, E to);371372/**373* Returns a copy of this set.374*375* @return a copy of this set376*/377@SuppressWarnings("unchecked")378public EnumSet<E> clone() {379try {380return (EnumSet<E>) super.clone();381} catch(CloneNotSupportedException e) {382throw new AssertionError(e);383}384}385386/**387* Complements the contents of this enum set.388*/389abstract void complement();390391/**392* Throws an exception if e is not of the correct type for this enum set.393*/394final void typeCheck(E e) {395Class<?> eClass = e.getClass();396if (eClass != elementType && eClass.getSuperclass() != elementType)397throw new ClassCastException(eClass + " != " + elementType);398}399400/**401* Returns all of the values comprising E.402* The result is uncloned, cached, and shared by all callers.403*/404private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {405return SharedSecrets.getJavaLangAccess()406.getEnumConstantsShared(elementType);407}408409/**410* This class is used to serialize all EnumSet instances, regardless of411* implementation type. It captures their "logical contents" and they412* are reconstructed using public static factories. This is necessary413* to ensure that the existence of a particular implementation type is414* an implementation detail.415*416* @serial include417*/418private static class SerializationProxy <E extends Enum<E>>419implements java.io.Serializable420{421/**422* The element type of this enum set.423*424* @serial425*/426private final Class<E> elementType;427428/**429* The elements contained in this enum set.430*431* @serial432*/433private final Enum<?>[] elements;434435SerializationProxy(EnumSet<E> set) {436elementType = set.elementType;437elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);438}439440// instead of cast to E, we should perhaps use elementType.cast()441// to avoid injection of forged stream, but it will slow the implementation442@SuppressWarnings("unchecked")443private Object readResolve() {444EnumSet<E> result = EnumSet.noneOf(elementType);445for (Enum<?> e : elements)446result.add((E)e);447return result;448}449450private static final long serialVersionUID = 362491234563181265L;451}452453Object writeReplace() {454return new SerializationProxy<>(this);455}456457// readObject method for the serialization proxy pattern458// See Effective Java, Second Ed., Item 78.459private void readObject(java.io.ObjectInputStream stream)460throws java.io.InvalidObjectException {461throw new java.io.InvalidObjectException("Proxy required");462}463}464465466