• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package java.util;
17 
18 // BEGIN android-added
19 
20 import java.io.Serializable;
21 import org.apache.harmony.kernel.vm.LangAccess;
22 
23 /**
24  * An EnumSet is a specialized Set to be used with enums as keys.
25  */
26 public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
27         implements Cloneable, Serializable {
28     // BEGIN android-added
29     /*
30      * null-ok; package access to {@code java.lang}, set during
31      * first need. This shouldn't be used directly. Instead, use {@link
32      * SpecialAccess#LANG}, which is guaranteed to be initialized.
33      */
34     static /*package*/ LangAccess LANG_BOOTSTRAP = null;
35     // END android-added
36 
37     private static final long serialVersionUID = 1009687484059888093L;
38 
39     final Class<E> elementClass;
40 
EnumSet(Class<E> cls)41     EnumSet(Class<E> cls) {
42         elementClass = cls;
43     }
44 
45     /**
46      * Creates an empty enum set. The permitted elements are of type
47      * Class&lt;E&gt;.
48      *
49      * @param elementType
50      *            the class object for the elements contained.
51      * @return an empty enum set, with permitted elements of type {@code
52      *         elementType}.
53      * @throws ClassCastException
54      *             if the specified element type is not and enum type.
55      */
noneOf(Class<E> elementType)56     public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
57         if (!elementType.isEnum()) {
58             throw new ClassCastException();
59         }
60         // BEGIN android-changed
61         E[] enums = SpecialAccess.LANG.getEnumValuesInOrder(elementType);
62         if (enums.length <= 64) {
63             return new MiniEnumSet<E>(elementType, enums);
64         }
65         return new HugeEnumSet<E>(elementType, enums);
66         // END android-changed
67     }
68 
69     /**
70      * Creates an enum set filled with all the enum elements of the specified
71      * {@code elementType}.
72      *
73      * @param elementType
74      *            the class object for the elements contained.
75      * @return an enum set with elements solely from the specified element type.
76      * @throws ClassCastException
77      *             if the specified element type is not and enum type.
78      */
allOf(Class<E> elementType)79     public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
80         EnumSet<E> set = noneOf(elementType);
81         set.complement();
82         return set;
83     }
84 
85     /**
86      * Creates an enum set. All the contained elements are of type
87      * Class&lt;E&gt;, and the contained elements are the same as those
88      * contained in {@code s}.
89      *
90      * @param s
91      *            the enum set from which to copy.
92      * @return an enum set with all the elements from the specified enum set.
93      * @throws ClassCastException
94      *             if the specified element type is not and enum type.
95      */
copyOf(EnumSet<E> s)96     public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
97         EnumSet<E> set = EnumSet.noneOf(s.elementClass);
98         set.addAll(s);
99         return set;
100     }
101 
102     /**
103      * Creates an enum set. The contained elements are the same as those
104      * contained in collection {@code c}. If c is an enum set, invoking this
105      * method is the same as invoking {@link #copyOf(EnumSet)}.
106      *
107      * @param c
108      *            the collection from which to copy. if it is not an enum set,
109      *            it must not be empty.
110      * @return an enum set with all the elements from the specified collection.
111      * @throws IllegalArgumentException
112      *             if c is not an enum set and contains no elements at all.
113      * @throws NullPointerException
114      *             if {@code c} is {@code null}.
115      */
copyOf(Collection<E> c)116     public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
117         if (c instanceof EnumSet) {
118             return copyOf((EnumSet<E>) c);
119         }
120         if (c.isEmpty()) {
121             throw new IllegalArgumentException();
122         }
123         Iterator<E> iterator = c.iterator();
124         E element = iterator.next();
125         EnumSet<E> set = EnumSet.noneOf(element.getDeclaringClass());
126         set.add(element);
127         while (iterator.hasNext()) {
128             set.add(iterator.next());
129         }
130         return set;
131     }
132 
133     /**
134      * Creates an enum set. All the contained elements complement those from the
135      * specified enum set.
136      *
137      * @param s
138      *            the specified enum set.
139      * @return an enum set with all the elements complementary to those from the
140      *         specified enum set.
141      * @throws NullPointerException
142      *             if {@code s} is {@code null}.
143      */
complementOf(EnumSet<E> s)144     public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
145         EnumSet<E> set = EnumSet.noneOf(s.elementClass);
146         set.addAll(s);
147         set.complement();
148         return set;
149     }
150 
complement()151     abstract void complement();
152 
153     /**
154      * Creates a new enum set, containing only the specified element. There are
155      * six overloadings of the method. They accept from one to five elements
156      * respectively. The sixth one receives an arbitrary number of elements, and
157      * runs slower than those that only receive a fixed number of elements.
158      *
159      * @param e
160      *            the element to be initially contained.
161      * @return an enum set containing the specified element.
162      * @throws NullPointerException
163      *             if {@code e} is {@code null}.
164      */
of(E e)165     public static <E extends Enum<E>> EnumSet<E> of(E e) {
166         EnumSet<E> set = EnumSet.noneOf(e.getDeclaringClass());
167         set.add(e);
168         return set;
169     }
170 
171     /**
172      * Creates a new enum set, containing only the specified elements. There are
173      * six overloadings of the method. They accept from one to five elements
174      * respectively. The sixth one receives an arbitrary number of elements, and
175      * runs slower than those that only receive a fixed number of elements.
176      *
177      * @param e1
178      *            the initially contained element.
179      * @param e2
180      *            another initially contained element.
181      * @return an enum set containing the specified elements.
182      * @throws NullPointerException
183      *             if any of the specified elements is {@code null}.
184      */
of(E e1, E e2)185     public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
186         EnumSet<E> set = of(e1);
187         set.add(e2);
188         return set;
189     }
190 
191     /**
192      * Creates a new enum set, containing only the specified elements. There are
193      * six overloadings of the method. They accept from one to five elements
194      * respectively. The sixth one receives an arbitrary number of elements, and
195      * runs slower than those that only receive a fixed number of elements.
196      *
197      * @param e1
198      *            the initially contained element.
199      * @param e2
200      *            another initially contained element.
201      * @param e3
202      *            another initially contained element.
203      * @return an enum set containing the specified elements.
204      * @throws NullPointerException
205      *             if any of the specified elements is {@code null}.
206      */
of(E e1, E e2, E e3)207     public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
208         EnumSet<E> set = of(e1, e2);
209         set.add(e3);
210         return set;
211     }
212 
213     /**
214      * Creates a new enum set, containing only the specified elements. There are
215      * six overloadings of the method. They accept from one to five elements
216      * respectively. The sixth one receives an arbitrary number of elements, and
217      * runs slower than those that only receive a fixed number of elements.
218      *
219      * @param e1
220      *            the initially contained element.
221      * @param e2
222      *            another initially contained element.
223      * @param e3
224      *            another initially contained element.
225      * @param e4
226      *            another initially contained element.
227      * @return an enum set containing the specified elements.
228      * @throws NullPointerException
229      *             if any of the specified elements is {@code null}.
230      */
of(E e1, E e2, E e3, E e4)231     public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
232         EnumSet<E> set = of(e1, e2, e3);
233         set.add(e4);
234         return set;
235     }
236 
237     /**
238      * Creates a new enum set, containing only the specified elements. There are
239      * six overloadings of the method. They accept from one to five elements
240      * respectively. The sixth one receives an arbitrary number of elements, and
241      * runs slower than those that only receive a fixed number of elements.
242      *
243      * @param e1
244      *            the initially contained element.
245      * @param e2
246      *            another initially contained element.
247      * @param e3
248      *            another initially contained element.
249      * @param e4
250      *            another initially contained element.
251      * @param e5
252      *            another initially contained element.
253      * @return an enum set containing the specified elements.
254      * @throws NullPointerException
255      *             if any of the specified elements is {@code null}.
256      */
of(E e1, E e2, E e3, E e4, E e5)257     public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5) {
258         EnumSet<E> set = of(e1, e2, e3, e4);
259         set.add(e5);
260         return set;
261     }
262 
263     /**
264      * Creates a new enum set, containing only the specified elements. It can
265      * receive an arbitrary number of elements, and runs slower than those only
266      * receiving a fixed number of elements.
267      *
268      * @param start
269      *            the first initially contained element.
270      * @param others
271      *            the other initially contained elements.
272      * @return an enum set containing the specified elements.
273      * @throws NullPointerException
274      *             if any of the specified elements is {@code null}.
275      */
of(E start, E... others)276     public static <E extends Enum<E>> EnumSet<E> of(E start, E... others) {
277         EnumSet<E> set = of(start);
278         for (E e : others) {
279             set.add(e);
280         }
281         return set;
282     }
283 
284     /**
285      * Creates an enum set containing all the elements within the range defined
286      * by {@code start} and {@code end} (inclusive). All the elements must be in
287      * order.
288      *
289      * @param start
290      *            the element used to define the beginning of the range.
291      * @param end
292      *            the element used to define the end of the range.
293      * @return an enum set with elements in the range from start to end.
294      * @throws NullPointerException
295      *             if any one of {@code start} or {@code end} is {@code null}.
296      * @throws IllegalArgumentException
297      *             if {@code start} is behind {@code end}.
298      */
range(E start, E end)299     public static <E extends Enum<E>> EnumSet<E> range(E start, E end) {
300         if (start.compareTo(end) > 0) {
301             throw new IllegalArgumentException();
302         }
303         EnumSet<E> set = EnumSet.noneOf(start.getDeclaringClass());
304         set.setRange(start, end);
305         return set;
306     }
307 
setRange(E start, E end)308     abstract void setRange(E start, E end);
309 
310     /**
311      * Creates a new enum set with the same elements as those contained in this
312      * enum set.
313      *
314      * @return a new enum set with the same elements as those contained in this
315      *         enum set.
316      */
317     @SuppressWarnings("unchecked")
318     @Override
clone()319     public EnumSet<E> clone() {
320         try {
321             return (EnumSet<E>) super.clone();
322         } catch (CloneNotSupportedException e) {
323             throw new AssertionError(e);
324         }
325     }
326 
isValidType(Class<?> cls)327     boolean isValidType(Class<?> cls) {
328         return cls == elementClass || cls.getSuperclass() == elementClass;
329     }
330 
331     private static class SerializationProxy<E extends Enum<E>> implements
332             Serializable {
333 
334         private static final long serialVersionUID = 362491234563181265L;
335 
336         private Class<E> elementType;
337 
338         private E[] elements;
339 
readResolve()340         private Object readResolve() {
341             EnumSet<E> set = EnumSet.noneOf(elementType);
342             for (E e : elements) {
343                 set.add(e);
344             }
345             return set;
346         }
347     }
348 
349     @SuppressWarnings("unchecked")
writeReplace()350     Object writeReplace() {
351         SerializationProxy proxy = new SerializationProxy();
352         proxy.elements = toArray(new Enum[0]);
353         proxy.elementType = elementClass;
354         return proxy;
355     }
356 }
357