< prev index next >

src/java.base/share/classes/java/util/EnumSet.java

Print this page




  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util;
  27 
  28 import sun.misc.SharedSecrets;
  29 
  30 /**
  31  * A specialized {@link Set} implementation for use with enum types.  All of
  32  * the elements in an enum set must come from a single enum type that is
  33  * specified, explicitly or implicitly, when the set is created.  Enum sets
  34  * are represented internally as bit vectors.  This representation is
  35  * extremely compact and efficient. The space and time performance of this
  36  * class should be good enough to allow its use as a high-quality, typesafe
  37  * alternative to traditional <tt>int</tt>-based "bit flags."  Even bulk
  38  * operations (such as <tt>containsAll</tt> and <tt>retainAll</tt>) should
  39  * run very quickly if their argument is also an enum set.
  40  *
  41  * <p>The iterator returned by the <tt>iterator</tt> method traverses the
  42  * elements in their <i>natural order</i> (the order in which the enum
  43  * constants are declared).  The returned iterator is <i>weakly
  44  * consistent</i>: it will never throw {@link ConcurrentModificationException}
  45  * and it may or may not show the effects of any modifications to the set that
  46  * occur while the iteration is in progress.
  47  *
  48  * <p>Null elements are not permitted.  Attempts to insert a null element
  49  * will throw {@link NullPointerException}.  Attempts to test for the
  50  * presence of a null element or to remove one will, however, function
  51  * properly.
  52  *
  53  * <P>Like most collection implementations, <tt>EnumSet</tt> is not
  54  * synchronized.  If multiple threads access an enum set concurrently, and at
  55  * least one of the threads modifies the set, it should be synchronized
  56  * externally.  This is typically accomplished by synchronizing on some
  57  * object that naturally encapsulates the enum set.  If no such object exists,
  58  * the set should be "wrapped" using the {@link Collections#synchronizedSet}
  59  * method.  This is best done at creation time, to prevent accidental
  60  * unsynchronized access:
  61  *
  62  * <pre>
  63  * Set&lt;MyEnum&gt; s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));
  64  * </pre>
  65  *
  66  * <p>Implementation note: All basic operations execute in constant time.
  67  * They are likely (though not guaranteed) to be much faster than their
  68  * {@link HashSet} counterparts.  Even bulk operations execute in
  69  * constant time if their argument is also an enum set.
  70  *
  71  * <p>This class is a member of the
  72  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  73  * Java Collections Framework</a>.


  89 
  90     /**
  91      * All of the values comprising T.  (Cached for performance.)
  92      */
  93     final Enum<?>[] universe;
  94 
  95     private static Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];
  96 
  97     EnumSet(Class<E>elementType, Enum<?>[] universe) {
  98         this.elementType = elementType;
  99         this.universe    = universe;
 100     }
 101 
 102     /**
 103      * Creates an empty enum set with the specified element type.
 104      *
 105      * @param <E> The class of the elements in the set
 106      * @param elementType the class object of the element type for this enum
 107      *     set
 108      * @return An empty enum set of the specified type.
 109      * @throws NullPointerException if <tt>elementType</tt> is null
 110      */
 111     public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
 112         Enum<?>[] universe = getUniverse(elementType);
 113         if (universe == null)
 114             throw new ClassCastException(elementType + " not an enum");
 115 
 116         if (universe.length <= 64)
 117             return new RegularEnumSet<>(elementType, universe);
 118         else
 119             return new JumboEnumSet<>(elementType, universe);
 120     }
 121 
 122     /**
 123      * Creates an enum set containing all of the elements in the specified
 124      * element type.
 125      *
 126      * @param <E> The class of the elements in the set
 127      * @param elementType the class object of the element type for this enum
 128      *     set
 129      * @return An enum set containing all the elements in the specified type.
 130      * @throws NullPointerException if <tt>elementType</tt> is null
 131      */
 132     public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
 133         EnumSet<E> result = noneOf(elementType);
 134         result.addAll();
 135         return result;
 136     }
 137 
 138     /**
 139      * Adds all of the elements from the appropriate enum type to this enum
 140      * set, which is empty prior to the call.
 141      */
 142     abstract void addAll();
 143 
 144     /**
 145      * Creates an enum set with the same element type as the specified enum
 146      * set, initially containing the same elements (if any).
 147      *
 148      * @param <E> The class of the elements in the set
 149      * @param s the enum set from which to initialize this enum set
 150      * @return A copy of the specified enum set.
 151      * @throws NullPointerException if <tt>s</tt> is null
 152      */
 153     public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
 154         return s.clone();
 155     }
 156 
 157     /**
 158      * Creates an enum set initialized from the specified collection.  If
 159      * the specified collection is an <tt>EnumSet</tt> instance, this static
 160      * factory method behaves identically to {@link #copyOf(EnumSet)}.
 161      * Otherwise, the specified collection must contain at least one element
 162      * (in order to determine the new enum set's element type).
 163      *
 164      * @param <E> The class of the elements in the collection
 165      * @param c the collection from which to initialize this enum set
 166      * @return An enum set initialized from the given collection.
 167      * @throws IllegalArgumentException if <tt>c</tt> is not an
 168      *     <tt>EnumSet</tt> instance and contains no elements
 169      * @throws NullPointerException if <tt>c</tt> is null
 170      */
 171     public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
 172         if (c instanceof EnumSet) {
 173             return ((EnumSet<E>)c).clone();
 174         } else {
 175             if (c.isEmpty())
 176                 throw new IllegalArgumentException("Collection is empty");
 177             Iterator<E> i = c.iterator();
 178             E first = i.next();
 179             EnumSet<E> result = EnumSet.of(first);
 180             while (i.hasNext())
 181                 result.add(i.next());
 182             return result;
 183         }
 184     }
 185 
 186     /**
 187      * Creates an enum set with the same element type as the specified enum
 188      * set, initially containing all the elements of this type that are
 189      * <i>not</i> contained in the specified set.
 190      *
 191      * @param <E> The class of the elements in the enum set
 192      * @param s the enum set from whose complement to initialize this enum set
 193      * @return The complement of the specified set in this set
 194      * @throws NullPointerException if <tt>s</tt> is null
 195      */
 196     public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
 197         EnumSet<E> result = copyOf(s);
 198         result.complement();
 199         return result;
 200     }
 201 
 202     /**
 203      * Creates an enum set initially containing the specified element.
 204      *
 205      * Overloadings of this method exist to initialize an enum set with
 206      * one through five elements.  A sixth overloading is provided that
 207      * uses the varargs feature.  This overloading may be used to create
 208      * an enum set initially containing an arbitrary number of elements, but
 209      * is likely to run slower than the overloadings that do not use varargs.
 210      *
 211      * @param <E> The class of the specified element and of the set
 212      * @param e the element that this set is to contain initially
 213      * @throws NullPointerException if <tt>e</tt> is null
 214      * @return an enum set initially containing the specified element
 215      */
 216     public static <E extends Enum<E>> EnumSet<E> of(E e) {
 217         EnumSet<E> result = noneOf(e.getDeclaringClass());
 218         result.add(e);
 219         return result;
 220     }
 221 
 222     /**
 223      * Creates an enum set initially containing the specified elements.
 224      *
 225      * Overloadings of this method exist to initialize an enum set with
 226      * one through five elements.  A sixth overloading is provided that
 227      * uses the varargs feature.  This overloading may be used to create
 228      * an enum set initially containing an arbitrary number of elements, but
 229      * is likely to run slower than the overloadings that do not use varargs.
 230      *
 231      * @param <E> The class of the parameter elements and of the set
 232      * @param e1 an element that this set is to contain initially
 233      * @param e2 another element that this set is to contain initially


 315         EnumSet<E> result = noneOf(e1.getDeclaringClass());
 316         result.add(e1);
 317         result.add(e2);
 318         result.add(e3);
 319         result.add(e4);
 320         result.add(e5);
 321         return result;
 322     }
 323 
 324     /**
 325      * Creates an enum set initially containing the specified elements.
 326      * This factory, whose parameter list uses the varargs feature, may
 327      * be used to create an enum set initially containing an arbitrary
 328      * number of elements, but it is likely to run slower than the overloadings
 329      * that do not use varargs.
 330      *
 331      * @param <E> The class of the parameter elements and of the set
 332      * @param first an element that the set is to contain initially
 333      * @param rest the remaining elements the set is to contain initially
 334      * @throws NullPointerException if any of the specified elements are null,
 335      *     or if <tt>rest</tt> is null
 336      * @return an enum set initially containing the specified elements
 337      */
 338     @SafeVarargs
 339     public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
 340         EnumSet<E> result = noneOf(first.getDeclaringClass());
 341         result.add(first);
 342         for (E e : rest)
 343             result.add(e);
 344         return result;
 345     }
 346 
 347     /**
 348      * Creates an enum set initially containing all of the elements in the
 349      * range defined by the two specified endpoints.  The returned set will
 350      * contain the endpoints themselves, which may be identical but must not
 351      * be out of order.
 352      *
 353      * @param <E> The class of the parameter elements and of the set
 354      * @param from the first element in the range
 355      * @param to the last element in the range




  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util;
  27 
  28 import sun.misc.SharedSecrets;
  29 
  30 /**
  31  * A specialized {@link Set} implementation for use with enum types.  All of
  32  * the elements in an enum set must come from a single enum type that is
  33  * specified, explicitly or implicitly, when the set is created.  Enum sets
  34  * are represented internally as bit vectors.  This representation is
  35  * extremely compact and efficient. The space and time performance of this
  36  * class should be good enough to allow its use as a high-quality, typesafe
  37  * alternative to traditional {@code int}-based "bit flags."  Even bulk
  38  * operations (such as {@code containsAll} and {@code retainAll}) should
  39  * run very quickly if their argument is also an enum set.
  40  *
  41  * <p>The iterator returned by the {@code iterator} method traverses the
  42  * elements in their <i>natural order</i> (the order in which the enum
  43  * constants are declared).  The returned iterator is <i>weakly
  44  * consistent</i>: it will never throw {@link ConcurrentModificationException}
  45  * and it may or may not show the effects of any modifications to the set that
  46  * occur while the iteration is in progress.
  47  *
  48  * <p>Null elements are not permitted.  Attempts to insert a null element
  49  * will throw {@link NullPointerException}.  Attempts to test for the
  50  * presence of a null element or to remove one will, however, function
  51  * properly.
  52  *
  53  * <P>Like most collection implementations, {@code EnumSet} is not
  54  * synchronized.  If multiple threads access an enum set concurrently, and at
  55  * least one of the threads modifies the set, it should be synchronized
  56  * externally.  This is typically accomplished by synchronizing on some
  57  * object that naturally encapsulates the enum set.  If no such object exists,
  58  * the set should be "wrapped" using the {@link Collections#synchronizedSet}
  59  * method.  This is best done at creation time, to prevent accidental
  60  * unsynchronized access:
  61  *
  62  * <pre>
  63  * Set&lt;MyEnum&gt; s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));
  64  * </pre>
  65  *
  66  * <p>Implementation note: All basic operations execute in constant time.
  67  * They are likely (though not guaranteed) to be much faster than their
  68  * {@link HashSet} counterparts.  Even bulk operations execute in
  69  * constant time if their argument is also an enum set.
  70  *
  71  * <p>This class is a member of the
  72  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  73  * Java Collections Framework</a>.


  89 
  90     /**
  91      * All of the values comprising T.  (Cached for performance.)
  92      */
  93     final Enum<?>[] universe;
  94 
  95     private static Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];
  96 
  97     EnumSet(Class<E>elementType, Enum<?>[] universe) {
  98         this.elementType = elementType;
  99         this.universe    = universe;
 100     }
 101 
 102     /**
 103      * Creates an empty enum set with the specified element type.
 104      *
 105      * @param <E> The class of the elements in the set
 106      * @param elementType the class object of the element type for this enum
 107      *     set
 108      * @return An empty enum set of the specified type.
 109      * @throws NullPointerException if {@code elementType} is null
 110      */
 111     public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
 112         Enum<?>[] universe = getUniverse(elementType);
 113         if (universe == null)
 114             throw new ClassCastException(elementType + " not an enum");
 115 
 116         if (universe.length <= 64)
 117             return new RegularEnumSet<>(elementType, universe);
 118         else
 119             return new JumboEnumSet<>(elementType, universe);
 120     }
 121 
 122     /**
 123      * Creates an enum set containing all of the elements in the specified
 124      * element type.
 125      *
 126      * @param <E> The class of the elements in the set
 127      * @param elementType the class object of the element type for this enum
 128      *     set
 129      * @return An enum set containing all the elements in the specified type.
 130      * @throws NullPointerException if {@code elementType} is null
 131      */
 132     public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
 133         EnumSet<E> result = noneOf(elementType);
 134         result.addAll();
 135         return result;
 136     }
 137 
 138     /**
 139      * Adds all of the elements from the appropriate enum type to this enum
 140      * set, which is empty prior to the call.
 141      */
 142     abstract void addAll();
 143 
 144     /**
 145      * Creates an enum set with the same element type as the specified enum
 146      * set, initially containing the same elements (if any).
 147      *
 148      * @param <E> The class of the elements in the set
 149      * @param s the enum set from which to initialize this enum set
 150      * @return A copy of the specified enum set.
 151      * @throws NullPointerException if {@code s} is null
 152      */
 153     public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
 154         return s.clone();
 155     }
 156 
 157     /**
 158      * Creates an enum set initialized from the specified collection.  If
 159      * the specified collection is an {@code EnumSet} instance, this static
 160      * factory method behaves identically to {@link #copyOf(EnumSet)}.
 161      * Otherwise, the specified collection must contain at least one element
 162      * (in order to determine the new enum set's element type).
 163      *
 164      * @param <E> The class of the elements in the collection
 165      * @param c the collection from which to initialize this enum set
 166      * @return An enum set initialized from the given collection.
 167      * @throws IllegalArgumentException if {@code c} is not an
 168      *     {@code EnumSet} instance and contains no elements
 169      * @throws NullPointerException if {@code c} is null
 170      */
 171     public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
 172         if (c instanceof EnumSet) {
 173             return ((EnumSet<E>)c).clone();
 174         } else {
 175             if (c.isEmpty())
 176                 throw new IllegalArgumentException("Collection is empty");
 177             Iterator<E> i = c.iterator();
 178             E first = i.next();
 179             EnumSet<E> result = EnumSet.of(first);
 180             while (i.hasNext())
 181                 result.add(i.next());
 182             return result;
 183         }
 184     }
 185 
 186     /**
 187      * Creates an enum set with the same element type as the specified enum
 188      * set, initially containing all the elements of this type that are
 189      * <i>not</i> contained in the specified set.
 190      *
 191      * @param <E> The class of the elements in the enum set
 192      * @param s the enum set from whose complement to initialize this enum set
 193      * @return The complement of the specified set in this set
 194      * @throws NullPointerException if {@code s} is null
 195      */
 196     public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
 197         EnumSet<E> result = copyOf(s);
 198         result.complement();
 199         return result;
 200     }
 201 
 202     /**
 203      * Creates an enum set initially containing the specified element.
 204      *
 205      * Overloadings of this method exist to initialize an enum set with
 206      * one through five elements.  A sixth overloading is provided that
 207      * uses the varargs feature.  This overloading may be used to create
 208      * an enum set initially containing an arbitrary number of elements, but
 209      * is likely to run slower than the overloadings that do not use varargs.
 210      *
 211      * @param <E> The class of the specified element and of the set
 212      * @param e the element that this set is to contain initially
 213      * @throws NullPointerException if {@code e} is null
 214      * @return an enum set initially containing the specified element
 215      */
 216     public static <E extends Enum<E>> EnumSet<E> of(E e) {
 217         EnumSet<E> result = noneOf(e.getDeclaringClass());
 218         result.add(e);
 219         return result;
 220     }
 221 
 222     /**
 223      * Creates an enum set initially containing the specified elements.
 224      *
 225      * Overloadings of this method exist to initialize an enum set with
 226      * one through five elements.  A sixth overloading is provided that
 227      * uses the varargs feature.  This overloading may be used to create
 228      * an enum set initially containing an arbitrary number of elements, but
 229      * is likely to run slower than the overloadings that do not use varargs.
 230      *
 231      * @param <E> The class of the parameter elements and of the set
 232      * @param e1 an element that this set is to contain initially
 233      * @param e2 another element that this set is to contain initially


 315         EnumSet<E> result = noneOf(e1.getDeclaringClass());
 316         result.add(e1);
 317         result.add(e2);
 318         result.add(e3);
 319         result.add(e4);
 320         result.add(e5);
 321         return result;
 322     }
 323 
 324     /**
 325      * Creates an enum set initially containing the specified elements.
 326      * This factory, whose parameter list uses the varargs feature, may
 327      * be used to create an enum set initially containing an arbitrary
 328      * number of elements, but it is likely to run slower than the overloadings
 329      * that do not use varargs.
 330      *
 331      * @param <E> The class of the parameter elements and of the set
 332      * @param first an element that the set is to contain initially
 333      * @param rest the remaining elements the set is to contain initially
 334      * @throws NullPointerException if any of the specified elements are null,
 335      *     or if {@code rest} is null
 336      * @return an enum set initially containing the specified elements
 337      */
 338     @SafeVarargs
 339     public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
 340         EnumSet<E> result = noneOf(first.getDeclaringClass());
 341         result.add(first);
 342         for (E e : rest)
 343             result.add(e);
 344         return result;
 345     }
 346 
 347     /**
 348      * Creates an enum set initially containing all of the elements in the
 349      * range defined by the two specified endpoints.  The returned set will
 350      * contain the endpoints themselves, which may be identical but must not
 351      * be out of order.
 352      *
 353      * @param <E> The class of the parameter elements and of the set
 354      * @param from the first element in the range
 355      * @param to the last element in the range


< prev index next >