Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/util/EnumSet.java
38829 views
1
/*
2
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
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>.
74
*
75
* @author Josh Bloch
76
* @since 1.5
77
* @see EnumMap
78
* @serial exclude
79
*/
80
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
81
implements Cloneable, java.io.Serializable
82
{
83
/**
84
* The class of all the elements of this set.
85
*/
86
final Class<E> elementType;
87
88
/**
89
* All of the values comprising T. (Cached for performance.)
90
*/
91
final Enum<?>[] universe;
92
93
private static Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];
94
95
EnumSet(Class<E>elementType, Enum<?>[] universe) {
96
this.elementType = elementType;
97
this.universe = universe;
98
}
99
100
/**
101
* Creates an empty enum set with the specified element type.
102
*
103
* @param <E> The class of the elements in the set
104
* @param elementType the class object of the element type for this enum
105
* set
106
* @return An empty enum set of the specified type.
107
* @throws NullPointerException if <tt>elementType</tt> is null
108
*/
109
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
110
Enum<?>[] universe = getUniverse(elementType);
111
if (universe == null)
112
throw new ClassCastException(elementType + " not an enum");
113
114
if (universe.length <= 64)
115
return new RegularEnumSet<>(elementType, universe);
116
else
117
return new JumboEnumSet<>(elementType, universe);
118
}
119
120
/**
121
* Creates an enum set containing all of the elements in the specified
122
* element type.
123
*
124
* @param <E> The class of the elements in the set
125
* @param elementType the class object of the element type for this enum
126
* set
127
* @return An enum set containing all the elements in the specified type.
128
* @throws NullPointerException if <tt>elementType</tt> is null
129
*/
130
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
131
EnumSet<E> result = noneOf(elementType);
132
result.addAll();
133
return result;
134
}
135
136
/**
137
* Adds all of the elements from the appropriate enum type to this enum
138
* set, which is empty prior to the call.
139
*/
140
abstract void addAll();
141
142
/**
143
* Creates an enum set with the same element type as the specified enum
144
* set, initially containing the same elements (if any).
145
*
146
* @param <E> The class of the elements in the set
147
* @param s the enum set from which to initialize this enum set
148
* @return A copy of the specified enum set.
149
* @throws NullPointerException if <tt>s</tt> is null
150
*/
151
public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
152
return s.clone();
153
}
154
155
/**
156
* Creates an enum set initialized from the specified collection. If
157
* the specified collection is an <tt>EnumSet</tt> instance, this static
158
* factory method behaves identically to {@link #copyOf(EnumSet)}.
159
* Otherwise, the specified collection must contain at least one element
160
* (in order to determine the new enum set's element type).
161
*
162
* @param <E> The class of the elements in the collection
163
* @param c the collection from which to initialize this enum set
164
* @return An enum set initialized from the given collection.
165
* @throws IllegalArgumentException if <tt>c</tt> is not an
166
* <tt>EnumSet</tt> instance and contains no elements
167
* @throws NullPointerException if <tt>c</tt> is null
168
*/
169
public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
170
if (c instanceof EnumSet) {
171
return ((EnumSet<E>)c).clone();
172
} else {
173
if (c.isEmpty())
174
throw new IllegalArgumentException("Collection is empty");
175
Iterator<E> i = c.iterator();
176
E first = i.next();
177
EnumSet<E> result = EnumSet.of(first);
178
while (i.hasNext())
179
result.add(i.next());
180
return result;
181
}
182
}
183
184
/**
185
* Creates an enum set with the same element type as the specified enum
186
* set, initially containing all the elements of this type that are
187
* <i>not</i> contained in the specified set.
188
*
189
* @param <E> The class of the elements in the enum set
190
* @param s the enum set from whose complement to initialize this enum set
191
* @return The complement of the specified set in this set
192
* @throws NullPointerException if <tt>s</tt> is null
193
*/
194
public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
195
EnumSet<E> result = copyOf(s);
196
result.complement();
197
return result;
198
}
199
200
/**
201
* Creates an enum set initially containing the specified element.
202
*
203
* Overloadings of this method exist to initialize an enum set with
204
* one through five elements. A sixth overloading is provided that
205
* uses the varargs feature. This overloading may be used to create
206
* an enum set initially containing an arbitrary number of elements, but
207
* is likely to run slower than the overloadings that do not use varargs.
208
*
209
* @param <E> The class of the specified element and of the set
210
* @param e the element that this set is to contain initially
211
* @throws NullPointerException if <tt>e</tt> is null
212
* @return an enum set initially containing the specified element
213
*/
214
public static <E extends Enum<E>> EnumSet<E> of(E e) {
215
EnumSet<E> result = noneOf(e.getDeclaringClass());
216
result.add(e);
217
return result;
218
}
219
220
/**
221
* Creates an enum set initially containing the specified elements.
222
*
223
* Overloadings of this method exist to initialize an enum set with
224
* one through five elements. A sixth overloading is provided that
225
* uses the varargs feature. This overloading may be used to create
226
* an enum set initially containing an arbitrary number of elements, but
227
* is likely to run slower than the overloadings that do not use varargs.
228
*
229
* @param <E> The class of the parameter elements and of the set
230
* @param e1 an element that this set is to contain initially
231
* @param e2 another element that this set is to contain initially
232
* @throws NullPointerException if any parameters are null
233
* @return an enum set initially containing the specified elements
234
*/
235
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
236
EnumSet<E> result = noneOf(e1.getDeclaringClass());
237
result.add(e1);
238
result.add(e2);
239
return result;
240
}
241
242
/**
243
* Creates an enum set initially containing the specified elements.
244
*
245
* Overloadings of this method exist to initialize an enum set with
246
* one through five elements. A sixth overloading is provided that
247
* uses the varargs feature. This overloading may be used to create
248
* an enum set initially containing an arbitrary number of elements, but
249
* is likely to run slower than the overloadings that do not use varargs.
250
*
251
* @param <E> The class of the parameter elements and of the set
252
* @param e1 an element that this set is to contain initially
253
* @param e2 another element that this set is to contain initially
254
* @param e3 another element that this set is to contain initially
255
* @throws NullPointerException if any parameters are null
256
* @return an enum set initially containing the specified elements
257
*/
258
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
259
EnumSet<E> result = noneOf(e1.getDeclaringClass());
260
result.add(e1);
261
result.add(e2);
262
result.add(e3);
263
return result;
264
}
265
266
/**
267
* Creates an enum set initially containing the specified elements.
268
*
269
* Overloadings of this method exist to initialize an enum set with
270
* one through five elements. A sixth overloading is provided that
271
* uses the varargs feature. This overloading may be used to create
272
* an enum set initially containing an arbitrary number of elements, but
273
* is likely to run slower than the overloadings that do not use varargs.
274
*
275
* @param <E> The class of the parameter elements and of the set
276
* @param e1 an element that this set is to contain initially
277
* @param e2 another element that this set is to contain initially
278
* @param e3 another element that this set is to contain initially
279
* @param e4 another element that this set is to contain initially
280
* @throws NullPointerException if any parameters are null
281
* @return an enum set initially containing the specified elements
282
*/
283
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
284
EnumSet<E> result = noneOf(e1.getDeclaringClass());
285
result.add(e1);
286
result.add(e2);
287
result.add(e3);
288
result.add(e4);
289
return result;
290
}
291
292
/**
293
* Creates an enum set initially containing the specified elements.
294
*
295
* Overloadings of this method exist to initialize an enum set with
296
* one through five elements. A sixth overloading is provided that
297
* uses the varargs feature. This overloading may be used to create
298
* an enum set initially containing an arbitrary number of elements, but
299
* is likely to run slower than the overloadings that do not use varargs.
300
*
301
* @param <E> The class of the parameter elements and of the set
302
* @param e1 an element that this set is to contain initially
303
* @param e2 another element that this set is to contain initially
304
* @param e3 another element that this set is to contain initially
305
* @param e4 another element that this set is to contain initially
306
* @param e5 another element that this set is to contain initially
307
* @throws NullPointerException if any parameters are null
308
* @return an enum set initially containing the specified elements
309
*/
310
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4,
311
E e5)
312
{
313
EnumSet<E> result = noneOf(e1.getDeclaringClass());
314
result.add(e1);
315
result.add(e2);
316
result.add(e3);
317
result.add(e4);
318
result.add(e5);
319
return result;
320
}
321
322
/**
323
* Creates an enum set initially containing the specified elements.
324
* This factory, whose parameter list uses the varargs feature, may
325
* be used to create an enum set initially containing an arbitrary
326
* number of elements, but it is likely to run slower than the overloadings
327
* that do not use varargs.
328
*
329
* @param <E> The class of the parameter elements and of the set
330
* @param first an element that the set is to contain initially
331
* @param rest the remaining elements the set is to contain initially
332
* @throws NullPointerException if any of the specified elements are null,
333
* or if <tt>rest</tt> is null
334
* @return an enum set initially containing the specified elements
335
*/
336
@SafeVarargs
337
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
338
EnumSet<E> result = noneOf(first.getDeclaringClass());
339
result.add(first);
340
for (E e : rest)
341
result.add(e);
342
return result;
343
}
344
345
/**
346
* Creates an enum set initially containing all of the elements in the
347
* range defined by the two specified endpoints. The returned set will
348
* contain the endpoints themselves, which may be identical but must not
349
* be out of order.
350
*
351
* @param <E> The class of the parameter elements and of the set
352
* @param from the first element in the range
353
* @param to the last element in the range
354
* @throws NullPointerException if {@code from} or {@code to} are null
355
* @throws IllegalArgumentException if {@code from.compareTo(to) > 0}
356
* @return an enum set initially containing all of the elements in the
357
* range defined by the two specified endpoints
358
*/
359
public static <E extends Enum<E>> EnumSet<E> range(E from, E to) {
360
if (from.compareTo(to) > 0)
361
throw new IllegalArgumentException(from + " > " + to);
362
EnumSet<E> result = noneOf(from.getDeclaringClass());
363
result.addRange(from, to);
364
return result;
365
}
366
367
/**
368
* Adds the specified range to this enum set, which is empty prior
369
* to the call.
370
*/
371
abstract void addRange(E from, E to);
372
373
/**
374
* Returns a copy of this set.
375
*
376
* @return a copy of this set
377
*/
378
@SuppressWarnings("unchecked")
379
public EnumSet<E> clone() {
380
try {
381
return (EnumSet<E>) super.clone();
382
} catch(CloneNotSupportedException e) {
383
throw new AssertionError(e);
384
}
385
}
386
387
/**
388
* Complements the contents of this enum set.
389
*/
390
abstract void complement();
391
392
/**
393
* Throws an exception if e is not of the correct type for this enum set.
394
*/
395
final void typeCheck(E e) {
396
Class<?> eClass = e.getClass();
397
if (eClass != elementType && eClass.getSuperclass() != elementType)
398
throw new ClassCastException(eClass + " != " + elementType);
399
}
400
401
/**
402
* Returns all of the values comprising E.
403
* The result is uncloned, cached, and shared by all callers.
404
*/
405
private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {
406
return SharedSecrets.getJavaLangAccess()
407
.getEnumConstantsShared(elementType);
408
}
409
410
/**
411
* This class is used to serialize all EnumSet instances, regardless of
412
* implementation type. It captures their "logical contents" and they
413
* are reconstructed using public static factories. This is necessary
414
* to ensure that the existence of a particular implementation type is
415
* an implementation detail.
416
*
417
* @serial include
418
*/
419
private static class SerializationProxy <E extends Enum<E>>
420
implements java.io.Serializable
421
{
422
/**
423
* The element type of this enum set.
424
*
425
* @serial
426
*/
427
private final Class<E> elementType;
428
429
/**
430
* The elements contained in this enum set.
431
*
432
* @serial
433
*/
434
private final Enum<?>[] elements;
435
436
SerializationProxy(EnumSet<E> set) {
437
elementType = set.elementType;
438
elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
439
}
440
441
// instead of cast to E, we should perhaps use elementType.cast()
442
// to avoid injection of forged stream, but it will slow the implementation
443
@SuppressWarnings("unchecked")
444
private Object readResolve() {
445
EnumSet<E> result = EnumSet.noneOf(elementType);
446
for (Enum<?> e : elements)
447
result.add((E)e);
448
return result;
449
}
450
451
private static final long serialVersionUID = 362491234563181265L;
452
}
453
454
Object writeReplace() {
455
return new SerializationProxy<>(this);
456
}
457
458
// readObject method for the serialization proxy pattern
459
// See Effective Java, Second Ed., Item 78.
460
private void readObject(java.io.ObjectInputStream stream)
461
throws java.io.InvalidObjectException {
462
throw new java.io.InvalidObjectException("Proxy required");
463
}
464
}
465
466