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