1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/emul/compact/src/main/java/java/util/EnumMap.java Sun Sep 22 21:49:42 2013 +0200
1.3 @@ -0,0 +1,799 @@
1.4 +/*
1.5 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.util;
1.30 +
1.31 +import java.util.Map.Entry;
1.32 +import sun.misc.SharedSecrets;
1.33 +
1.34 +/**
1.35 + * A specialized {@link Map} implementation for use with enum type keys. All
1.36 + * of the keys in an enum map must come from a single enum type that is
1.37 + * specified, explicitly or implicitly, when the map is created. Enum maps
1.38 + * are represented internally as arrays. This representation is extremely
1.39 + * compact and efficient.
1.40 + *
1.41 + * <p>Enum maps are maintained in the <i>natural order</i> of their keys
1.42 + * (the order in which the enum constants are declared). This is reflected
1.43 + * in the iterators returned by the collections views ({@link #keySet()},
1.44 + * {@link #entrySet()}, and {@link #values()}).
1.45 + *
1.46 + * <p>Iterators returned by the collection views are <i>weakly consistent</i>:
1.47 + * they will never throw {@link ConcurrentModificationException} and they may
1.48 + * or may not show the effects of any modifications to the map that occur while
1.49 + * the iteration is in progress.
1.50 + *
1.51 + * <p>Null keys are not permitted. Attempts to insert a null key will
1.52 + * throw {@link NullPointerException}. Attempts to test for the
1.53 + * presence of a null key or to remove one will, however, function properly.
1.54 + * Null values are permitted.
1.55 +
1.56 + * <P>Like most collection implementations <tt>EnumMap</tt> is not
1.57 + * synchronized. If multiple threads access an enum map concurrently, and at
1.58 + * least one of the threads modifies the map, it should be synchronized
1.59 + * externally. This is typically accomplished by synchronizing on some
1.60 + * object that naturally encapsulates the enum map. If no such object exists,
1.61 + * the map should be "wrapped" using the {@link Collections#synchronizedMap}
1.62 + * method. This is best done at creation time, to prevent accidental
1.63 + * unsynchronized access:
1.64 + *
1.65 + * <pre>
1.66 + * Map<EnumKey, V> m
1.67 + * = Collections.synchronizedMap(new EnumMap<EnumKey, V>(...));
1.68 + * </pre>
1.69 + *
1.70 + * <p>Implementation note: All basic operations execute in constant time.
1.71 + * They are likely (though not guaranteed) to be faster than their
1.72 + * {@link HashMap} counterparts.
1.73 + *
1.74 + * <p>This class is a member of the
1.75 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
1.76 + * Java Collections Framework</a>.
1.77 + *
1.78 + * @author Josh Bloch
1.79 + * @see EnumSet
1.80 + * @since 1.5
1.81 + */
1.82 +public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
1.83 + implements java.io.Serializable, Cloneable
1.84 +{
1.85 + /**
1.86 + * The <tt>Class</tt> object for the enum type of all the keys of this map.
1.87 + *
1.88 + * @serial
1.89 + */
1.90 + private final Class<K> keyType;
1.91 +
1.92 + /**
1.93 + * All of the values comprising K. (Cached for performance.)
1.94 + */
1.95 + private transient K[] keyUniverse;
1.96 +
1.97 + /**
1.98 + * Array representation of this map. The ith element is the value
1.99 + * to which universe[i] is currently mapped, or null if it isn't
1.100 + * mapped to anything, or NULL if it's mapped to null.
1.101 + */
1.102 + private transient Object[] vals;
1.103 +
1.104 + /**
1.105 + * The number of mappings in this map.
1.106 + */
1.107 + private transient int size = 0;
1.108 +
1.109 + /**
1.110 + * Distinguished non-null value for representing null values.
1.111 + */
1.112 + private static final Object NULL = new Integer(0);
1.113 +
1.114 + private Object maskNull(Object value) {
1.115 + return (value == null ? NULL : value);
1.116 + }
1.117 +
1.118 + private V unmaskNull(Object value) {
1.119 + return (V) (value == NULL ? null : value);
1.120 + }
1.121 +
1.122 + private static final Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
1.123 +
1.124 + /**
1.125 + * Creates an empty enum map with the specified key type.
1.126 + *
1.127 + * @param keyType the class object of the key type for this enum map
1.128 + * @throws NullPointerException if <tt>keyType</tt> is null
1.129 + */
1.130 + public EnumMap(Class<K> keyType) {
1.131 + this.keyType = keyType;
1.132 + keyUniverse = getKeyUniverse(keyType);
1.133 + vals = new Object[keyUniverse.length];
1.134 + }
1.135 +
1.136 + /**
1.137 + * Creates an enum map with the same key type as the specified enum
1.138 + * map, initially containing the same mappings (if any).
1.139 + *
1.140 + * @param m the enum map from which to initialize this enum map
1.141 + * @throws NullPointerException if <tt>m</tt> is null
1.142 + */
1.143 + public EnumMap(EnumMap<K, ? extends V> m) {
1.144 + keyType = m.keyType;
1.145 + keyUniverse = m.keyUniverse;
1.146 + vals = m.vals.clone();
1.147 + size = m.size;
1.148 + }
1.149 +
1.150 + /**
1.151 + * Creates an enum map initialized from the specified map. If the
1.152 + * specified map is an <tt>EnumMap</tt> instance, this constructor behaves
1.153 + * identically to {@link #EnumMap(EnumMap)}. Otherwise, the specified map
1.154 + * must contain at least one mapping (in order to determine the new
1.155 + * enum map's key type).
1.156 + *
1.157 + * @param m the map from which to initialize this enum map
1.158 + * @throws IllegalArgumentException if <tt>m</tt> is not an
1.159 + * <tt>EnumMap</tt> instance and contains no mappings
1.160 + * @throws NullPointerException if <tt>m</tt> is null
1.161 + */
1.162 + public EnumMap(Map<K, ? extends V> m) {
1.163 + if (m instanceof EnumMap) {
1.164 + EnumMap<K, ? extends V> em = (EnumMap<K, ? extends V>) m;
1.165 + keyType = em.keyType;
1.166 + keyUniverse = em.keyUniverse;
1.167 + vals = em.vals.clone();
1.168 + size = em.size;
1.169 + } else {
1.170 + if (m.isEmpty())
1.171 + throw new IllegalArgumentException("Specified map is empty");
1.172 + keyType = m.keySet().iterator().next().getDeclaringClass();
1.173 + keyUniverse = getKeyUniverse(keyType);
1.174 + vals = new Object[keyUniverse.length];
1.175 + putAll(m);
1.176 + }
1.177 + }
1.178 +
1.179 + // Query Operations
1.180 +
1.181 + /**
1.182 + * Returns the number of key-value mappings in this map.
1.183 + *
1.184 + * @return the number of key-value mappings in this map
1.185 + */
1.186 + public int size() {
1.187 + return size;
1.188 + }
1.189 +
1.190 + /**
1.191 + * Returns <tt>true</tt> if this map maps one or more keys to the
1.192 + * specified value.
1.193 + *
1.194 + * @param value the value whose presence in this map is to be tested
1.195 + * @return <tt>true</tt> if this map maps one or more keys to this value
1.196 + */
1.197 + public boolean containsValue(Object value) {
1.198 + value = maskNull(value);
1.199 +
1.200 + for (Object val : vals)
1.201 + if (value.equals(val))
1.202 + return true;
1.203 +
1.204 + return false;
1.205 + }
1.206 +
1.207 + /**
1.208 + * Returns <tt>true</tt> if this map contains a mapping for the specified
1.209 + * key.
1.210 + *
1.211 + * @param key the key whose presence in this map is to be tested
1.212 + * @return <tt>true</tt> if this map contains a mapping for the specified
1.213 + * key
1.214 + */
1.215 + public boolean containsKey(Object key) {
1.216 + return isValidKey(key) && vals[((Enum)key).ordinal()] != null;
1.217 + }
1.218 +
1.219 + private boolean containsMapping(Object key, Object value) {
1.220 + return isValidKey(key) &&
1.221 + maskNull(value).equals(vals[((Enum)key).ordinal()]);
1.222 + }
1.223 +
1.224 + /**
1.225 + * Returns the value to which the specified key is mapped,
1.226 + * or {@code null} if this map contains no mapping for the key.
1.227 + *
1.228 + * <p>More formally, if this map contains a mapping from a key
1.229 + * {@code k} to a value {@code v} such that {@code (key == k)},
1.230 + * then this method returns {@code v}; otherwise it returns
1.231 + * {@code null}. (There can be at most one such mapping.)
1.232 + *
1.233 + * <p>A return value of {@code null} does not <i>necessarily</i>
1.234 + * indicate that the map contains no mapping for the key; it's also
1.235 + * possible that the map explicitly maps the key to {@code null}.
1.236 + * The {@link #containsKey containsKey} operation may be used to
1.237 + * distinguish these two cases.
1.238 + */
1.239 + public V get(Object key) {
1.240 + return (isValidKey(key) ?
1.241 + unmaskNull(vals[((Enum)key).ordinal()]) : null);
1.242 + }
1.243 +
1.244 + // Modification Operations
1.245 +
1.246 + /**
1.247 + * Associates the specified value with the specified key in this map.
1.248 + * If the map previously contained a mapping for this key, the old
1.249 + * value is replaced.
1.250 + *
1.251 + * @param key the key with which the specified value is to be associated
1.252 + * @param value the value to be associated with the specified key
1.253 + *
1.254 + * @return the previous value associated with specified key, or
1.255 + * <tt>null</tt> if there was no mapping for key. (A <tt>null</tt>
1.256 + * return can also indicate that the map previously associated
1.257 + * <tt>null</tt> with the specified key.)
1.258 + * @throws NullPointerException if the specified key is null
1.259 + */
1.260 + public V put(K key, V value) {
1.261 + typeCheck(key);
1.262 +
1.263 + int index = key.ordinal();
1.264 + Object oldValue = vals[index];
1.265 + vals[index] = maskNull(value);
1.266 + if (oldValue == null)
1.267 + size++;
1.268 + return unmaskNull(oldValue);
1.269 + }
1.270 +
1.271 + /**
1.272 + * Removes the mapping for this key from this map if present.
1.273 + *
1.274 + * @param key the key whose mapping is to be removed from the map
1.275 + * @return the previous value associated with specified key, or
1.276 + * <tt>null</tt> if there was no entry for key. (A <tt>null</tt>
1.277 + * return can also indicate that the map previously associated
1.278 + * <tt>null</tt> with the specified key.)
1.279 + */
1.280 + public V remove(Object key) {
1.281 + if (!isValidKey(key))
1.282 + return null;
1.283 + int index = ((Enum)key).ordinal();
1.284 + Object oldValue = vals[index];
1.285 + vals[index] = null;
1.286 + if (oldValue != null)
1.287 + size--;
1.288 + return unmaskNull(oldValue);
1.289 + }
1.290 +
1.291 + private boolean removeMapping(Object key, Object value) {
1.292 + if (!isValidKey(key))
1.293 + return false;
1.294 + int index = ((Enum)key).ordinal();
1.295 + if (maskNull(value).equals(vals[index])) {
1.296 + vals[index] = null;
1.297 + size--;
1.298 + return true;
1.299 + }
1.300 + return false;
1.301 + }
1.302 +
1.303 + /**
1.304 + * Returns true if key is of the proper type to be a key in this
1.305 + * enum map.
1.306 + */
1.307 + private boolean isValidKey(Object key) {
1.308 + if (key == null)
1.309 + return false;
1.310 +
1.311 + // Cheaper than instanceof Enum followed by getDeclaringClass
1.312 + Class keyClass = key.getClass();
1.313 + return keyClass == keyType || keyClass.getSuperclass() == keyType;
1.314 + }
1.315 +
1.316 + // Bulk Operations
1.317 +
1.318 + /**
1.319 + * Copies all of the mappings from the specified map to this map.
1.320 + * These mappings will replace any mappings that this map had for
1.321 + * any of the keys currently in the specified map.
1.322 + *
1.323 + * @param m the mappings to be stored in this map
1.324 + * @throws NullPointerException the specified map is null, or if
1.325 + * one or more keys in the specified map are null
1.326 + */
1.327 + public void putAll(Map<? extends K, ? extends V> m) {
1.328 + if (m instanceof EnumMap) {
1.329 + EnumMap<? extends K, ? extends V> em =
1.330 + (EnumMap<? extends K, ? extends V>)m;
1.331 + if (em.keyType != keyType) {
1.332 + if (em.isEmpty())
1.333 + return;
1.334 + throw new ClassCastException(em.keyType + " != " + keyType);
1.335 + }
1.336 +
1.337 + for (int i = 0; i < keyUniverse.length; i++) {
1.338 + Object emValue = em.vals[i];
1.339 + if (emValue != null) {
1.340 + if (vals[i] == null)
1.341 + size++;
1.342 + vals[i] = emValue;
1.343 + }
1.344 + }
1.345 + } else {
1.346 + super.putAll(m);
1.347 + }
1.348 + }
1.349 +
1.350 + /**
1.351 + * Removes all mappings from this map.
1.352 + */
1.353 + public void clear() {
1.354 + Arrays.fill(vals, null);
1.355 + size = 0;
1.356 + }
1.357 +
1.358 + // Views
1.359 +
1.360 + /**
1.361 + * This field is initialized to contain an instance of the entry set
1.362 + * view the first time this view is requested. The view is stateless,
1.363 + * so there's no reason to create more than one.
1.364 + */
1.365 + private transient Set<Map.Entry<K,V>> entrySet = null;
1.366 +
1.367 + /**
1.368 + * Returns a {@link Set} view of the keys contained in this map.
1.369 + * The returned set obeys the general contract outlined in
1.370 + * {@link Map#keySet()}. The set's iterator will return the keys
1.371 + * in their natural order (the order in which the enum constants
1.372 + * are declared).
1.373 + *
1.374 + * @return a set view of the keys contained in this enum map
1.375 + */
1.376 + public Set<K> keySet() {
1.377 + Set<K> ks = keySet;
1.378 + if (ks != null)
1.379 + return ks;
1.380 + else
1.381 + return keySet = new KeySet();
1.382 + }
1.383 +
1.384 + private class KeySet extends AbstractSet<K> {
1.385 + public Iterator<K> iterator() {
1.386 + return new KeyIterator();
1.387 + }
1.388 + public int size() {
1.389 + return size;
1.390 + }
1.391 + public boolean contains(Object o) {
1.392 + return containsKey(o);
1.393 + }
1.394 + public boolean remove(Object o) {
1.395 + int oldSize = size;
1.396 + EnumMap.this.remove(o);
1.397 + return size != oldSize;
1.398 + }
1.399 + public void clear() {
1.400 + EnumMap.this.clear();
1.401 + }
1.402 + }
1.403 +
1.404 + /**
1.405 + * Returns a {@link Collection} view of the values contained in this map.
1.406 + * The returned collection obeys the general contract outlined in
1.407 + * {@link Map#values()}. The collection's iterator will return the
1.408 + * values in the order their corresponding keys appear in map,
1.409 + * which is their natural order (the order in which the enum constants
1.410 + * are declared).
1.411 + *
1.412 + * @return a collection view of the values contained in this map
1.413 + */
1.414 + public Collection<V> values() {
1.415 + Collection<V> vs = values;
1.416 + if (vs != null)
1.417 + return vs;
1.418 + else
1.419 + return values = new Values();
1.420 + }
1.421 +
1.422 + private class Values extends AbstractCollection<V> {
1.423 + public Iterator<V> iterator() {
1.424 + return new ValueIterator();
1.425 + }
1.426 + public int size() {
1.427 + return size;
1.428 + }
1.429 + public boolean contains(Object o) {
1.430 + return containsValue(o);
1.431 + }
1.432 + public boolean remove(Object o) {
1.433 + o = maskNull(o);
1.434 +
1.435 + for (int i = 0; i < vals.length; i++) {
1.436 + if (o.equals(vals[i])) {
1.437 + vals[i] = null;
1.438 + size--;
1.439 + return true;
1.440 + }
1.441 + }
1.442 + return false;
1.443 + }
1.444 + public void clear() {
1.445 + EnumMap.this.clear();
1.446 + }
1.447 + }
1.448 +
1.449 + /**
1.450 + * Returns a {@link Set} view of the mappings contained in this map.
1.451 + * The returned set obeys the general contract outlined in
1.452 + * {@link Map#keySet()}. The set's iterator will return the
1.453 + * mappings in the order their keys appear in map, which is their
1.454 + * natural order (the order in which the enum constants are declared).
1.455 + *
1.456 + * @return a set view of the mappings contained in this enum map
1.457 + */
1.458 + public Set<Map.Entry<K,V>> entrySet() {
1.459 + Set<Map.Entry<K,V>> es = entrySet;
1.460 + if (es != null)
1.461 + return es;
1.462 + else
1.463 + return entrySet = new EntrySet();
1.464 + }
1.465 +
1.466 + private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
1.467 + public Iterator<Map.Entry<K,V>> iterator() {
1.468 + return new EntryIterator();
1.469 + }
1.470 +
1.471 + public boolean contains(Object o) {
1.472 + if (!(o instanceof Map.Entry))
1.473 + return false;
1.474 + Map.Entry entry = (Map.Entry)o;
1.475 + return containsMapping(entry.getKey(), entry.getValue());
1.476 + }
1.477 + public boolean remove(Object o) {
1.478 + if (!(o instanceof Map.Entry))
1.479 + return false;
1.480 + Map.Entry entry = (Map.Entry)o;
1.481 + return removeMapping(entry.getKey(), entry.getValue());
1.482 + }
1.483 + public int size() {
1.484 + return size;
1.485 + }
1.486 + public void clear() {
1.487 + EnumMap.this.clear();
1.488 + }
1.489 + public Object[] toArray() {
1.490 + return fillEntryArray(new Object[size]);
1.491 + }
1.492 + @SuppressWarnings("unchecked")
1.493 + public <T> T[] toArray(T[] a) {
1.494 + int size = size();
1.495 + if (a.length < size)
1.496 + a = (T[])java.lang.reflect.Array
1.497 + .newInstance(a.getClass().getComponentType(), size);
1.498 + if (a.length > size)
1.499 + a[size] = null;
1.500 + return (T[]) fillEntryArray(a);
1.501 + }
1.502 + private Object[] fillEntryArray(Object[] a) {
1.503 + int j = 0;
1.504 + for (int i = 0; i < vals.length; i++)
1.505 + if (vals[i] != null)
1.506 + a[j++] = new AbstractMap.SimpleEntry<>(
1.507 + keyUniverse[i], unmaskNull(vals[i]));
1.508 + return a;
1.509 + }
1.510 + }
1.511 +
1.512 + private abstract class EnumMapIterator<T> implements Iterator<T> {
1.513 + // Lower bound on index of next element to return
1.514 + int index = 0;
1.515 +
1.516 + // Index of last returned element, or -1 if none
1.517 + int lastReturnedIndex = -1;
1.518 +
1.519 + public boolean hasNext() {
1.520 + while (index < vals.length && vals[index] == null)
1.521 + index++;
1.522 + return index != vals.length;
1.523 + }
1.524 +
1.525 + public void remove() {
1.526 + checkLastReturnedIndex();
1.527 +
1.528 + if (vals[lastReturnedIndex] != null) {
1.529 + vals[lastReturnedIndex] = null;
1.530 + size--;
1.531 + }
1.532 + lastReturnedIndex = -1;
1.533 + }
1.534 +
1.535 + private void checkLastReturnedIndex() {
1.536 + if (lastReturnedIndex < 0)
1.537 + throw new IllegalStateException();
1.538 + }
1.539 + }
1.540 +
1.541 + private class KeyIterator extends EnumMapIterator<K> {
1.542 + public K next() {
1.543 + if (!hasNext())
1.544 + throw new NoSuchElementException();
1.545 + lastReturnedIndex = index++;
1.546 + return keyUniverse[lastReturnedIndex];
1.547 + }
1.548 + }
1.549 +
1.550 + private class ValueIterator extends EnumMapIterator<V> {
1.551 + public V next() {
1.552 + if (!hasNext())
1.553 + throw new NoSuchElementException();
1.554 + lastReturnedIndex = index++;
1.555 + return unmaskNull(vals[lastReturnedIndex]);
1.556 + }
1.557 + }
1.558 +
1.559 + private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>> {
1.560 + private Entry lastReturnedEntry = null;
1.561 +
1.562 + public Map.Entry<K,V> next() {
1.563 + if (!hasNext())
1.564 + throw new NoSuchElementException();
1.565 + lastReturnedEntry = new Entry(index++);
1.566 + return lastReturnedEntry;
1.567 + }
1.568 +
1.569 + public void remove() {
1.570 + lastReturnedIndex =
1.571 + ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
1.572 + super.remove();
1.573 + lastReturnedEntry.index = lastReturnedIndex;
1.574 + lastReturnedEntry = null;
1.575 + }
1.576 +
1.577 + private class Entry implements Map.Entry<K,V> {
1.578 + private int index;
1.579 +
1.580 + private Entry(int index) {
1.581 + this.index = index;
1.582 + }
1.583 +
1.584 + public K getKey() {
1.585 + checkIndexForEntryUse();
1.586 + return keyUniverse[index];
1.587 + }
1.588 +
1.589 + public V getValue() {
1.590 + checkIndexForEntryUse();
1.591 + return unmaskNull(vals[index]);
1.592 + }
1.593 +
1.594 + public V setValue(V value) {
1.595 + checkIndexForEntryUse();
1.596 + V oldValue = unmaskNull(vals[index]);
1.597 + vals[index] = maskNull(value);
1.598 + return oldValue;
1.599 + }
1.600 +
1.601 + public boolean equals(Object o) {
1.602 + if (index < 0)
1.603 + return o == this;
1.604 +
1.605 + if (!(o instanceof Map.Entry))
1.606 + return false;
1.607 +
1.608 + Map.Entry e = (Map.Entry)o;
1.609 + V ourValue = unmaskNull(vals[index]);
1.610 + Object hisValue = e.getValue();
1.611 + return (e.getKey() == keyUniverse[index] &&
1.612 + (ourValue == hisValue ||
1.613 + (ourValue != null && ourValue.equals(hisValue))));
1.614 + }
1.615 +
1.616 + public int hashCode() {
1.617 + if (index < 0)
1.618 + return super.hashCode();
1.619 +
1.620 + return entryHashCode(index);
1.621 + }
1.622 +
1.623 + public String toString() {
1.624 + if (index < 0)
1.625 + return super.toString();
1.626 +
1.627 + return keyUniverse[index] + "="
1.628 + + unmaskNull(vals[index]);
1.629 + }
1.630 +
1.631 + private void checkIndexForEntryUse() {
1.632 + if (index < 0)
1.633 + throw new IllegalStateException("Entry was removed");
1.634 + }
1.635 + }
1.636 + }
1.637 +
1.638 + // Comparison and hashing
1.639 +
1.640 + /**
1.641 + * Compares the specified object with this map for equality. Returns
1.642 + * <tt>true</tt> if the given object is also a map and the two maps
1.643 + * represent the same mappings, as specified in the {@link
1.644 + * Map#equals(Object)} contract.
1.645 + *
1.646 + * @param o the object to be compared for equality with this map
1.647 + * @return <tt>true</tt> if the specified object is equal to this map
1.648 + */
1.649 + public boolean equals(Object o) {
1.650 + if (this == o)
1.651 + return true;
1.652 + if (o instanceof EnumMap)
1.653 + return equals((EnumMap)o);
1.654 + if (!(o instanceof Map))
1.655 + return false;
1.656 +
1.657 + Map<K,V> m = (Map<K,V>)o;
1.658 + if (size != m.size())
1.659 + return false;
1.660 +
1.661 + for (int i = 0; i < keyUniverse.length; i++) {
1.662 + if (null != vals[i]) {
1.663 + K key = keyUniverse[i];
1.664 + V value = unmaskNull(vals[i]);
1.665 + if (null == value) {
1.666 + if (!((null == m.get(key)) && m.containsKey(key)))
1.667 + return false;
1.668 + } else {
1.669 + if (!value.equals(m.get(key)))
1.670 + return false;
1.671 + }
1.672 + }
1.673 + }
1.674 +
1.675 + return true;
1.676 + }
1.677 +
1.678 + private boolean equals(EnumMap em) {
1.679 + if (em.keyType != keyType)
1.680 + return size == 0 && em.size == 0;
1.681 +
1.682 + // Key types match, compare each value
1.683 + for (int i = 0; i < keyUniverse.length; i++) {
1.684 + Object ourValue = vals[i];
1.685 + Object hisValue = em.vals[i];
1.686 + if (hisValue != ourValue &&
1.687 + (hisValue == null || !hisValue.equals(ourValue)))
1.688 + return false;
1.689 + }
1.690 + return true;
1.691 + }
1.692 +
1.693 + /**
1.694 + * Returns the hash code value for this map. The hash code of a map is
1.695 + * defined to be the sum of the hash codes of each entry in the map.
1.696 + */
1.697 + public int hashCode() {
1.698 + int h = 0;
1.699 +
1.700 + for (int i = 0; i < keyUniverse.length; i++) {
1.701 + if (null != vals[i]) {
1.702 + h += entryHashCode(i);
1.703 + }
1.704 + }
1.705 +
1.706 + return h;
1.707 + }
1.708 +
1.709 + private int entryHashCode(int index) {
1.710 + return (keyUniverse[index].hashCode() ^ vals[index].hashCode());
1.711 + }
1.712 +
1.713 + /**
1.714 + * Returns a shallow copy of this enum map. (The values themselves
1.715 + * are not cloned.
1.716 + *
1.717 + * @return a shallow copy of this enum map
1.718 + */
1.719 + public EnumMap<K, V> clone() {
1.720 + EnumMap<K, V> result = null;
1.721 + try {
1.722 + result = (EnumMap<K, V>) super.clone();
1.723 + } catch(CloneNotSupportedException e) {
1.724 + throw new AssertionError();
1.725 + }
1.726 + result.vals = result.vals.clone();
1.727 + return result;
1.728 + }
1.729 +
1.730 + /**
1.731 + * Throws an exception if e is not of the correct type for this enum set.
1.732 + */
1.733 + private void typeCheck(K key) {
1.734 + Class keyClass = key.getClass();
1.735 + if (keyClass != keyType && keyClass.getSuperclass() != keyType)
1.736 + throw new ClassCastException(keyClass + " != " + keyType);
1.737 + }
1.738 +
1.739 + /**
1.740 + * Returns all of the values comprising K.
1.741 + * The result is uncloned, cached, and shared by all callers.
1.742 + */
1.743 + private static <K extends Enum<K>> K[] getKeyUniverse(Class<K> keyType) {
1.744 + return SharedSecrets.getJavaLangAccess()
1.745 + .getEnumConstantsShared(keyType);
1.746 + }
1.747 +
1.748 + private static final long serialVersionUID = 458661240069192865L;
1.749 +
1.750 + /**
1.751 + * Save the state of the <tt>EnumMap</tt> instance to a stream (i.e.,
1.752 + * serialize it).
1.753 + *
1.754 + * @serialData The <i>size</i> of the enum map (the number of key-value
1.755 + * mappings) is emitted (int), followed by the key (Object)
1.756 + * and value (Object) for each key-value mapping represented
1.757 + * by the enum map.
1.758 + */
1.759 + private void writeObject(java.io.ObjectOutputStream s)
1.760 + throws java.io.IOException
1.761 + {
1.762 + // Write out the key type and any hidden stuff
1.763 + s.defaultWriteObject();
1.764 +
1.765 + // Write out size (number of Mappings)
1.766 + s.writeInt(size);
1.767 +
1.768 + // Write out keys and values (alternating)
1.769 + int entriesToBeWritten = size;
1.770 + for (int i = 0; entriesToBeWritten > 0; i++) {
1.771 + if (null != vals[i]) {
1.772 + s.writeObject(keyUniverse[i]);
1.773 + s.writeObject(unmaskNull(vals[i]));
1.774 + entriesToBeWritten--;
1.775 + }
1.776 + }
1.777 + }
1.778 +
1.779 + /**
1.780 + * Reconstitute the <tt>EnumMap</tt> instance from a stream (i.e.,
1.781 + * deserialize it).
1.782 + */
1.783 + private void readObject(java.io.ObjectInputStream s)
1.784 + throws java.io.IOException, ClassNotFoundException
1.785 + {
1.786 + // Read in the key type and any hidden stuff
1.787 + s.defaultReadObject();
1.788 +
1.789 + keyUniverse = getKeyUniverse(keyType);
1.790 + vals = new Object[keyUniverse.length];
1.791 +
1.792 + // Read in size (number of Mappings)
1.793 + int size = s.readInt();
1.794 +
1.795 + // Read the keys and values, and put the mappings in the HashMap
1.796 + for (int i = 0; i < size; i++) {
1.797 + K key = (K) s.readObject();
1.798 + V value = (V) s.readObject();
1.799 + put(key, value);
1.800 + }
1.801 + }
1.802 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/emul/compact/src/main/java/java/util/EnumSet.java Sun Sep 22 21:49:42 2013 +0200
2.3 @@ -0,0 +1,443 @@
2.4 +/*
2.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2.7 + *
2.8 + * This code is free software; you can redistribute it and/or modify it
2.9 + * under the terms of the GNU General Public License version 2 only, as
2.10 + * published by the Free Software Foundation. Oracle designates this
2.11 + * particular file as subject to the "Classpath" exception as provided
2.12 + * by Oracle in the LICENSE file that accompanied this code.
2.13 + *
2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2.17 + * version 2 for more details (a copy is included in the LICENSE file that
2.18 + * accompanied this code).
2.19 + *
2.20 + * You should have received a copy of the GNU General Public License version
2.21 + * 2 along with this work; if not, write to the Free Software Foundation,
2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2.23 + *
2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2.25 + * or visit www.oracle.com if you need additional information or have any
2.26 + * questions.
2.27 + */
2.28 +
2.29 +package java.util;
2.30 +
2.31 +import sun.misc.SharedSecrets;
2.32 +
2.33 +/**
2.34 + * A specialized {@link Set} implementation for use with enum types. All of
2.35 + * the elements in an enum set must come from a single enum type that is
2.36 + * specified, explicitly or implicitly, when the set is created. Enum sets
2.37 + * are represented internally as bit vectors. This representation is
2.38 + * extremely compact and efficient. The space and time performance of this
2.39 + * class should be good enough to allow its use as a high-quality, typesafe
2.40 + * alternative to traditional <tt>int</tt>-based "bit flags." Even bulk
2.41 + * operations (such as <tt>containsAll</tt> and <tt>retainAll</tt>) should
2.42 + * run very quickly if their argument is also an enum set.
2.43 + *
2.44 + * <p>The iterator returned by the <tt>iterator</tt> method traverses the
2.45 + * elements in their <i>natural order</i> (the order in which the enum
2.46 + * constants are declared). The returned iterator is <i>weakly
2.47 + * consistent</i>: it will never throw {@link ConcurrentModificationException}
2.48 + * and it may or may not show the effects of any modifications to the set that
2.49 + * occur while the iteration is in progress.
2.50 + *
2.51 + * <p>Null elements are not permitted. Attempts to insert a null element
2.52 + * will throw {@link NullPointerException}. Attempts to test for the
2.53 + * presence of a null element or to remove one will, however, function
2.54 + * properly.
2.55 + *
2.56 + * <P>Like most collection implementations, <tt>EnumSet</tt> is not
2.57 + * synchronized. If multiple threads access an enum set concurrently, and at
2.58 + * least one of the threads modifies the set, it should be synchronized
2.59 + * externally. This is typically accomplished by synchronizing on some
2.60 + * object that naturally encapsulates the enum set. If no such object exists,
2.61 + * the set should be "wrapped" using the {@link Collections#synchronizedSet}
2.62 + * method. This is best done at creation time, to prevent accidental
2.63 + * unsynchronized access:
2.64 + *
2.65 + * <pre>
2.66 + * Set<MyEnum> s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));
2.67 + * </pre>
2.68 + *
2.69 + * <p>Implementation note: All basic operations execute in constant time.
2.70 + * They are likely (though not guaranteed) to be much faster than their
2.71 + * {@link HashSet} counterparts. Even bulk operations execute in
2.72 + * constant time if their argument is also an enum set.
2.73 + *
2.74 + * <p>This class is a member of the
2.75 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
2.76 + * Java Collections Framework</a>.
2.77 + *
2.78 + * @author Josh Bloch
2.79 + * @since 1.5
2.80 + * @see EnumMap
2.81 + * @serial exclude
2.82 + */
2.83 +public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
2.84 + implements Cloneable, java.io.Serializable
2.85 +{
2.86 + /**
2.87 + * The class of all the elements of this set.
2.88 + */
2.89 + final Class<E> elementType;
2.90 +
2.91 + /**
2.92 + * All of the values comprising T. (Cached for performance.)
2.93 + */
2.94 + final Enum[] universe;
2.95 +
2.96 + private static Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
2.97 +
2.98 + EnumSet(Class<E>elementType, Enum[] universe) {
2.99 + this.elementType = elementType;
2.100 + this.universe = universe;
2.101 + }
2.102 +
2.103 + /**
2.104 + * Creates an empty enum set with the specified element type.
2.105 + *
2.106 + * @param elementType the class object of the element type for this enum
2.107 + * set
2.108 + * @throws NullPointerException if <tt>elementType</tt> is null
2.109 + */
2.110 + public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
2.111 + Enum[] universe = getUniverse(elementType);
2.112 + if (universe == null)
2.113 + throw new ClassCastException(elementType + " not an enum");
2.114 +
2.115 + if (universe.length <= 64)
2.116 + return new RegularEnumSet<>(elementType, universe);
2.117 + else
2.118 + return new JumboEnumSet<>(elementType, universe);
2.119 + }
2.120 +
2.121 + /**
2.122 + * Creates an enum set containing all of the elements in the specified
2.123 + * element type.
2.124 + *
2.125 + * @param elementType the class object of the element type for this enum
2.126 + * set
2.127 + * @throws NullPointerException if <tt>elementType</tt> is null
2.128 + */
2.129 + public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
2.130 + EnumSet<E> result = noneOf(elementType);
2.131 + result.addAll();
2.132 + return result;
2.133 + }
2.134 +
2.135 + /**
2.136 + * Adds all of the elements from the appropriate enum type to this enum
2.137 + * set, which is empty prior to the call.
2.138 + */
2.139 + abstract void addAll();
2.140 +
2.141 + /**
2.142 + * Creates an enum set with the same element type as the specified enum
2.143 + * set, initially containing the same elements (if any).
2.144 + *
2.145 + * @param s the enum set from which to initialize this enum set
2.146 + * @throws NullPointerException if <tt>s</tt> is null
2.147 + */
2.148 + public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
2.149 + return s.clone();
2.150 + }
2.151 +
2.152 + /**
2.153 + * Creates an enum set initialized from the specified collection. If
2.154 + * the specified collection is an <tt>EnumSet</tt> instance, this static
2.155 + * factory method behaves identically to {@link #copyOf(EnumSet)}.
2.156 + * Otherwise, the specified collection must contain at least one element
2.157 + * (in order to determine the new enum set's element type).
2.158 + *
2.159 + * @param c the collection from which to initialize this enum set
2.160 + * @throws IllegalArgumentException if <tt>c</tt> is not an
2.161 + * <tt>EnumSet</tt> instance and contains no elements
2.162 + * @throws NullPointerException if <tt>c</tt> is null
2.163 + */
2.164 + public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
2.165 + if (c instanceof EnumSet) {
2.166 + return ((EnumSet<E>)c).clone();
2.167 + } else {
2.168 + if (c.isEmpty())
2.169 + throw new IllegalArgumentException("Collection is empty");
2.170 + Iterator<E> i = c.iterator();
2.171 + E first = i.next();
2.172 + EnumSet<E> result = EnumSet.of(first);
2.173 + while (i.hasNext())
2.174 + result.add(i.next());
2.175 + return result;
2.176 + }
2.177 + }
2.178 +
2.179 + /**
2.180 + * Creates an enum set with the same element type as the specified enum
2.181 + * set, initially containing all the elements of this type that are
2.182 + * <i>not</i> contained in the specified set.
2.183 + *
2.184 + * @param s the enum set from whose complement to initialize this enum set
2.185 + * @throws NullPointerException if <tt>s</tt> is null
2.186 + */
2.187 + public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
2.188 + EnumSet<E> result = copyOf(s);
2.189 + result.complement();
2.190 + return result;
2.191 + }
2.192 +
2.193 + /**
2.194 + * Creates an enum set initially containing the specified element.
2.195 + *
2.196 + * Overloadings of this method exist to initialize an enum set with
2.197 + * one through five elements. A sixth overloading is provided that
2.198 + * uses the varargs feature. This overloading may be used to create
2.199 + * an enum set initially containing an arbitrary number of elements, but
2.200 + * is likely to run slower than the overloadings that do not use varargs.
2.201 + *
2.202 + * @param e the element that this set is to contain initially
2.203 + * @throws NullPointerException if <tt>e</tt> is null
2.204 + * @return an enum set initially containing the specified element
2.205 + */
2.206 + public static <E extends Enum<E>> EnumSet<E> of(E e) {
2.207 + EnumSet<E> result = noneOf(e.getDeclaringClass());
2.208 + result.add(e);
2.209 + return result;
2.210 + }
2.211 +
2.212 + /**
2.213 + * Creates an enum set initially containing the specified elements.
2.214 + *
2.215 + * Overloadings of this method exist to initialize an enum set with
2.216 + * one through five elements. A sixth overloading is provided that
2.217 + * uses the varargs feature. This overloading may be used to create
2.218 + * an enum set initially containing an arbitrary number of elements, but
2.219 + * is likely to run slower than the overloadings that do not use varargs.
2.220 + *
2.221 + * @param e1 an element that this set is to contain initially
2.222 + * @param e2 another element that this set is to contain initially
2.223 + * @throws NullPointerException if any parameters are null
2.224 + * @return an enum set initially containing the specified elements
2.225 + */
2.226 + public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
2.227 + EnumSet<E> result = noneOf(e1.getDeclaringClass());
2.228 + result.add(e1);
2.229 + result.add(e2);
2.230 + return result;
2.231 + }
2.232 +
2.233 + /**
2.234 + * Creates an enum set initially containing the specified elements.
2.235 + *
2.236 + * Overloadings of this method exist to initialize an enum set with
2.237 + * one through five elements. A sixth overloading is provided that
2.238 + * uses the varargs feature. This overloading may be used to create
2.239 + * an enum set initially containing an arbitrary number of elements, but
2.240 + * is likely to run slower than the overloadings that do not use varargs.
2.241 + *
2.242 + * @param e1 an element that this set is to contain initially
2.243 + * @param e2 another element that this set is to contain initially
2.244 + * @param e3 another element that this set is to contain initially
2.245 + * @throws NullPointerException if any parameters are null
2.246 + * @return an enum set initially containing the specified elements
2.247 + */
2.248 + public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
2.249 + EnumSet<E> result = noneOf(e1.getDeclaringClass());
2.250 + result.add(e1);
2.251 + result.add(e2);
2.252 + result.add(e3);
2.253 + return result;
2.254 + }
2.255 +
2.256 + /**
2.257 + * Creates an enum set initially containing the specified elements.
2.258 + *
2.259 + * Overloadings of this method exist to initialize an enum set with
2.260 + * one through five elements. A sixth overloading is provided that
2.261 + * uses the varargs feature. This overloading may be used to create
2.262 + * an enum set initially containing an arbitrary number of elements, but
2.263 + * is likely to run slower than the overloadings that do not use varargs.
2.264 + *
2.265 + * @param e1 an element that this set is to contain initially
2.266 + * @param e2 another element that this set is to contain initially
2.267 + * @param e3 another element that this set is to contain initially
2.268 + * @param e4 another element that this set is to contain initially
2.269 + * @throws NullPointerException if any parameters are null
2.270 + * @return an enum set initially containing the specified elements
2.271 + */
2.272 + public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
2.273 + EnumSet<E> result = noneOf(e1.getDeclaringClass());
2.274 + result.add(e1);
2.275 + result.add(e2);
2.276 + result.add(e3);
2.277 + result.add(e4);
2.278 + return result;
2.279 + }
2.280 +
2.281 + /**
2.282 + * Creates an enum set initially containing the specified elements.
2.283 + *
2.284 + * Overloadings of this method exist to initialize an enum set with
2.285 + * one through five elements. A sixth overloading is provided that
2.286 + * uses the varargs feature. This overloading may be used to create
2.287 + * an enum set initially containing an arbitrary number of elements, but
2.288 + * is likely to run slower than the overloadings that do not use varargs.
2.289 + *
2.290 + * @param e1 an element that this set is to contain initially
2.291 + * @param e2 another element that this set is to contain initially
2.292 + * @param e3 another element that this set is to contain initially
2.293 + * @param e4 another element that this set is to contain initially
2.294 + * @param e5 another element that this set is to contain initially
2.295 + * @throws NullPointerException if any parameters are null
2.296 + * @return an enum set initially containing the specified elements
2.297 + */
2.298 + public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4,
2.299 + E e5)
2.300 + {
2.301 + EnumSet<E> result = noneOf(e1.getDeclaringClass());
2.302 + result.add(e1);
2.303 + result.add(e2);
2.304 + result.add(e3);
2.305 + result.add(e4);
2.306 + result.add(e5);
2.307 + return result;
2.308 + }
2.309 +
2.310 + /**
2.311 + * Creates an enum set initially containing the specified elements.
2.312 + * This factory, whose parameter list uses the varargs feature, may
2.313 + * be used to create an enum set initially containing an arbitrary
2.314 + * number of elements, but it is likely to run slower than the overloadings
2.315 + * that do not use varargs.
2.316 + *
2.317 + * @param first an element that the set is to contain initially
2.318 + * @param rest the remaining elements the set is to contain initially
2.319 + * @throws NullPointerException if any of the specified elements are null,
2.320 + * or if <tt>rest</tt> is null
2.321 + * @return an enum set initially containing the specified elements
2.322 + */
2.323 + @SafeVarargs
2.324 + public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
2.325 + EnumSet<E> result = noneOf(first.getDeclaringClass());
2.326 + result.add(first);
2.327 + for (E e : rest)
2.328 + result.add(e);
2.329 + return result;
2.330 + }
2.331 +
2.332 + /**
2.333 + * Creates an enum set initially containing all of the elements in the
2.334 + * range defined by the two specified endpoints. The returned set will
2.335 + * contain the endpoints themselves, which may be identical but must not
2.336 + * be out of order.
2.337 + *
2.338 + * @param from the first element in the range
2.339 + * @param to the last element in the range
2.340 + * @throws NullPointerException if {@code from} or {@code to} are null
2.341 + * @throws IllegalArgumentException if {@code from.compareTo(to) > 0}
2.342 + * @return an enum set initially containing all of the elements in the
2.343 + * range defined by the two specified endpoints
2.344 + */
2.345 + public static <E extends Enum<E>> EnumSet<E> range(E from, E to) {
2.346 + if (from.compareTo(to) > 0)
2.347 + throw new IllegalArgumentException(from + " > " + to);
2.348 + EnumSet<E> result = noneOf(from.getDeclaringClass());
2.349 + result.addRange(from, to);
2.350 + return result;
2.351 + }
2.352 +
2.353 + /**
2.354 + * Adds the specified range to this enum set, which is empty prior
2.355 + * to the call.
2.356 + */
2.357 + abstract void addRange(E from, E to);
2.358 +
2.359 + /**
2.360 + * Returns a copy of this set.
2.361 + *
2.362 + * @return a copy of this set
2.363 + */
2.364 + public EnumSet<E> clone() {
2.365 + try {
2.366 + return (EnumSet<E>) super.clone();
2.367 + } catch(CloneNotSupportedException e) {
2.368 + throw new AssertionError(e);
2.369 + }
2.370 + }
2.371 +
2.372 + /**
2.373 + * Complements the contents of this enum set.
2.374 + */
2.375 + abstract void complement();
2.376 +
2.377 + /**
2.378 + * Throws an exception if e is not of the correct type for this enum set.
2.379 + */
2.380 + final void typeCheck(E e) {
2.381 + Class eClass = e.getClass();
2.382 + if (eClass != elementType && eClass.getSuperclass() != elementType)
2.383 + throw new ClassCastException(eClass + " != " + elementType);
2.384 + }
2.385 +
2.386 + /**
2.387 + * Returns all of the values comprising E.
2.388 + * The result is uncloned, cached, and shared by all callers.
2.389 + */
2.390 + private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {
2.391 + return SharedSecrets.getJavaLangAccess()
2.392 + .getEnumConstantsShared(elementType);
2.393 + }
2.394 +
2.395 + /**
2.396 + * This class is used to serialize all EnumSet instances, regardless of
2.397 + * implementation type. It captures their "logical contents" and they
2.398 + * are reconstructed using public static factories. This is necessary
2.399 + * to ensure that the existence of a particular implementation type is
2.400 + * an implementation detail.
2.401 + *
2.402 + * @serial include
2.403 + */
2.404 + private static class SerializationProxy <E extends Enum<E>>
2.405 + implements java.io.Serializable
2.406 + {
2.407 + /**
2.408 + * The element type of this enum set.
2.409 + *
2.410 + * @serial
2.411 + */
2.412 + private final Class<E> elementType;
2.413 +
2.414 + /**
2.415 + * The elements contained in this enum set.
2.416 + *
2.417 + * @serial
2.418 + */
2.419 + private final Enum[] elements;
2.420 +
2.421 + SerializationProxy(EnumSet<E> set) {
2.422 + elementType = set.elementType;
2.423 + elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
2.424 + }
2.425 +
2.426 + private Object readResolve() {
2.427 + EnumSet<E> result = EnumSet.noneOf(elementType);
2.428 + for (Enum e : elements)
2.429 + result.add((E)e);
2.430 + return result;
2.431 + }
2.432 +
2.433 + private static final long serialVersionUID = 362491234563181265L;
2.434 + }
2.435 +
2.436 + Object writeReplace() {
2.437 + return new SerializationProxy<>(this);
2.438 + }
2.439 +
2.440 + // readObject method for the serialization proxy pattern
2.441 + // See Effective Java, Second Ed., Item 78.
2.442 + private void readObject(java.io.ObjectInputStream stream)
2.443 + throws java.io.InvalidObjectException {
2.444 + throw new java.io.InvalidObjectException("Proxy required");
2.445 + }
2.446 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/emul/compact/src/main/java/java/util/JumboEnumSet.java Sun Sep 22 21:49:42 2013 +0200
3.3 @@ -0,0 +1,375 @@
3.4 +/*
3.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3.7 + *
3.8 + * This code is free software; you can redistribute it and/or modify it
3.9 + * under the terms of the GNU General Public License version 2 only, as
3.10 + * published by the Free Software Foundation. Oracle designates this
3.11 + * particular file as subject to the "Classpath" exception as provided
3.12 + * by Oracle in the LICENSE file that accompanied this code.
3.13 + *
3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3.17 + * version 2 for more details (a copy is included in the LICENSE file that
3.18 + * accompanied this code).
3.19 + *
3.20 + * You should have received a copy of the GNU General Public License version
3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3.23 + *
3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3.25 + * or visit www.oracle.com if you need additional information or have any
3.26 + * questions.
3.27 + */
3.28 +
3.29 +package java.util;
3.30 +
3.31 +/**
3.32 + * Private implementation class for EnumSet, for "jumbo" enum types
3.33 + * (i.e., those with more than 64 elements).
3.34 + *
3.35 + * @author Josh Bloch
3.36 + * @since 1.5
3.37 + * @serial exclude
3.38 + */
3.39 +class JumboEnumSet<E extends Enum<E>> extends EnumSet<E> {
3.40 + private static final long serialVersionUID = 334349849919042784L;
3.41 +
3.42 + /**
3.43 + * Bit vector representation of this set. The ith bit of the jth
3.44 + * element of this array represents the presence of universe[64*j +i]
3.45 + * in this set.
3.46 + */
3.47 + private long elements[];
3.48 +
3.49 + // Redundant - maintained for performance
3.50 + private int size = 0;
3.51 +
3.52 + JumboEnumSet(Class<E>elementType, Enum[] universe) {
3.53 + super(elementType, universe);
3.54 + elements = new long[(universe.length + 63) >>> 6];
3.55 + }
3.56 +
3.57 + void addRange(E from, E to) {
3.58 + int fromIndex = from.ordinal() >>> 6;
3.59 + int toIndex = to.ordinal() >>> 6;
3.60 +
3.61 + if (fromIndex == toIndex) {
3.62 + elements[fromIndex] = (-1L >>> (from.ordinal() - to.ordinal() - 1))
3.63 + << from.ordinal();
3.64 + } else {
3.65 + elements[fromIndex] = (-1L << from.ordinal());
3.66 + for (int i = fromIndex + 1; i < toIndex; i++)
3.67 + elements[i] = -1;
3.68 + elements[toIndex] = -1L >>> (63 - to.ordinal());
3.69 + }
3.70 + size = to.ordinal() - from.ordinal() + 1;
3.71 + }
3.72 +
3.73 + void addAll() {
3.74 + for (int i = 0; i < elements.length; i++)
3.75 + elements[i] = -1;
3.76 + elements[elements.length - 1] >>>= -universe.length;
3.77 + size = universe.length;
3.78 + }
3.79 +
3.80 + void complement() {
3.81 + for (int i = 0; i < elements.length; i++)
3.82 + elements[i] = ~elements[i];
3.83 + elements[elements.length - 1] &= (-1L >>> -universe.length);
3.84 + size = universe.length - size;
3.85 + }
3.86 +
3.87 + /**
3.88 + * Returns an iterator over the elements contained in this set. The
3.89 + * iterator traverses the elements in their <i>natural order</i> (which is
3.90 + * the order in which the enum constants are declared). The returned
3.91 + * Iterator is a "weakly consistent" iterator that will never throw {@link
3.92 + * ConcurrentModificationException}.
3.93 + *
3.94 + * @return an iterator over the elements contained in this set
3.95 + */
3.96 + public Iterator<E> iterator() {
3.97 + return new EnumSetIterator<>();
3.98 + }
3.99 +
3.100 + private class EnumSetIterator<E extends Enum<E>> implements Iterator<E> {
3.101 + /**
3.102 + * A bit vector representing the elements in the current "word"
3.103 + * of the set not yet returned by this iterator.
3.104 + */
3.105 + long unseen;
3.106 +
3.107 + /**
3.108 + * The index corresponding to unseen in the elements array.
3.109 + */
3.110 + int unseenIndex = 0;
3.111 +
3.112 + /**
3.113 + * The bit representing the last element returned by this iterator
3.114 + * but not removed, or zero if no such element exists.
3.115 + */
3.116 + long lastReturned = 0;
3.117 +
3.118 + /**
3.119 + * The index corresponding to lastReturned in the elements array.
3.120 + */
3.121 + int lastReturnedIndex = 0;
3.122 +
3.123 + EnumSetIterator() {
3.124 + unseen = elements[0];
3.125 + }
3.126 +
3.127 + public boolean hasNext() {
3.128 + while (unseen == 0 && unseenIndex < elements.length - 1)
3.129 + unseen = elements[++unseenIndex];
3.130 + return unseen != 0;
3.131 + }
3.132 +
3.133 + public E next() {
3.134 + if (!hasNext())
3.135 + throw new NoSuchElementException();
3.136 + lastReturned = unseen & -unseen;
3.137 + lastReturnedIndex = unseenIndex;
3.138 + unseen -= lastReturned;
3.139 + return (E) universe[(lastReturnedIndex << 6)
3.140 + + Long.numberOfTrailingZeros(lastReturned)];
3.141 + }
3.142 +
3.143 + public void remove() {
3.144 + if (lastReturned == 0)
3.145 + throw new IllegalStateException();
3.146 + final long oldElements = elements[lastReturnedIndex];
3.147 + elements[lastReturnedIndex] &= ~lastReturned;
3.148 + if (oldElements != elements[lastReturnedIndex]) {
3.149 + size--;
3.150 + }
3.151 + lastReturned = 0;
3.152 + }
3.153 + }
3.154 +
3.155 + /**
3.156 + * Returns the number of elements in this set.
3.157 + *
3.158 + * @return the number of elements in this set
3.159 + */
3.160 + public int size() {
3.161 + return size;
3.162 + }
3.163 +
3.164 + /**
3.165 + * Returns <tt>true</tt> if this set contains no elements.
3.166 + *
3.167 + * @return <tt>true</tt> if this set contains no elements
3.168 + */
3.169 + public boolean isEmpty() {
3.170 + return size == 0;
3.171 + }
3.172 +
3.173 + /**
3.174 + * Returns <tt>true</tt> if this set contains the specified element.
3.175 + *
3.176 + * @param e element to be checked for containment in this collection
3.177 + * @return <tt>true</tt> if this set contains the specified element
3.178 + */
3.179 + public boolean contains(Object e) {
3.180 + if (e == null)
3.181 + return false;
3.182 + Class eClass = e.getClass();
3.183 + if (eClass != elementType && eClass.getSuperclass() != elementType)
3.184 + return false;
3.185 +
3.186 + int eOrdinal = ((Enum)e).ordinal();
3.187 + return (elements[eOrdinal >>> 6] & (1L << eOrdinal)) != 0;
3.188 + }
3.189 +
3.190 + // Modification Operations
3.191 +
3.192 + /**
3.193 + * Adds the specified element to this set if it is not already present.
3.194 + *
3.195 + * @param e element to be added to this set
3.196 + * @return <tt>true</tt> if the set changed as a result of the call
3.197 + *
3.198 + * @throws NullPointerException if <tt>e</tt> is null
3.199 + */
3.200 + public boolean add(E e) {
3.201 + typeCheck(e);
3.202 +
3.203 + int eOrdinal = e.ordinal();
3.204 + int eWordNum = eOrdinal >>> 6;
3.205 +
3.206 + long oldElements = elements[eWordNum];
3.207 + elements[eWordNum] |= (1L << eOrdinal);
3.208 + boolean result = (elements[eWordNum] != oldElements);
3.209 + if (result)
3.210 + size++;
3.211 + return result;
3.212 + }
3.213 +
3.214 + /**
3.215 + * Removes the specified element from this set if it is present.
3.216 + *
3.217 + * @param e element to be removed from this set, if present
3.218 + * @return <tt>true</tt> if the set contained the specified element
3.219 + */
3.220 + public boolean remove(Object e) {
3.221 + if (e == null)
3.222 + return false;
3.223 + Class eClass = e.getClass();
3.224 + if (eClass != elementType && eClass.getSuperclass() != elementType)
3.225 + return false;
3.226 + int eOrdinal = ((Enum)e).ordinal();
3.227 + int eWordNum = eOrdinal >>> 6;
3.228 +
3.229 + long oldElements = elements[eWordNum];
3.230 + elements[eWordNum] &= ~(1L << eOrdinal);
3.231 + boolean result = (elements[eWordNum] != oldElements);
3.232 + if (result)
3.233 + size--;
3.234 + return result;
3.235 + }
3.236 +
3.237 + // Bulk Operations
3.238 +
3.239 + /**
3.240 + * Returns <tt>true</tt> if this set contains all of the elements
3.241 + * in the specified collection.
3.242 + *
3.243 + * @param c collection to be checked for containment in this set
3.244 + * @return <tt>true</tt> if this set contains all of the elements
3.245 + * in the specified collection
3.246 + * @throws NullPointerException if the specified collection is null
3.247 + */
3.248 + public boolean containsAll(Collection<?> c) {
3.249 + if (!(c instanceof JumboEnumSet))
3.250 + return super.containsAll(c);
3.251 +
3.252 + JumboEnumSet es = (JumboEnumSet)c;
3.253 + if (es.elementType != elementType)
3.254 + return es.isEmpty();
3.255 +
3.256 + for (int i = 0; i < elements.length; i++)
3.257 + if ((es.elements[i] & ~elements[i]) != 0)
3.258 + return false;
3.259 + return true;
3.260 + }
3.261 +
3.262 + /**
3.263 + * Adds all of the elements in the specified collection to this set.
3.264 + *
3.265 + * @param c collection whose elements are to be added to this set
3.266 + * @return <tt>true</tt> if this set changed as a result of the call
3.267 + * @throws NullPointerException if the specified collection or any of
3.268 + * its elements are null
3.269 + */
3.270 + public boolean addAll(Collection<? extends E> c) {
3.271 + if (!(c instanceof JumboEnumSet))
3.272 + return super.addAll(c);
3.273 +
3.274 + JumboEnumSet es = (JumboEnumSet)c;
3.275 + if (es.elementType != elementType) {
3.276 + if (es.isEmpty())
3.277 + return false;
3.278 + else
3.279 + throw new ClassCastException(
3.280 + es.elementType + " != " + elementType);
3.281 + }
3.282 +
3.283 + for (int i = 0; i < elements.length; i++)
3.284 + elements[i] |= es.elements[i];
3.285 + return recalculateSize();
3.286 + }
3.287 +
3.288 + /**
3.289 + * Removes from this set all of its elements that are contained in
3.290 + * the specified collection.
3.291 + *
3.292 + * @param c elements to be removed from this set
3.293 + * @return <tt>true</tt> if this set changed as a result of the call
3.294 + * @throws NullPointerException if the specified collection is null
3.295 + */
3.296 + public boolean removeAll(Collection<?> c) {
3.297 + if (!(c instanceof JumboEnumSet))
3.298 + return super.removeAll(c);
3.299 +
3.300 + JumboEnumSet es = (JumboEnumSet)c;
3.301 + if (es.elementType != elementType)
3.302 + return false;
3.303 +
3.304 + for (int i = 0; i < elements.length; i++)
3.305 + elements[i] &= ~es.elements[i];
3.306 + return recalculateSize();
3.307 + }
3.308 +
3.309 + /**
3.310 + * Retains only the elements in this set that are contained in the
3.311 + * specified collection.
3.312 + *
3.313 + * @param c elements to be retained in this set
3.314 + * @return <tt>true</tt> if this set changed as a result of the call
3.315 + * @throws NullPointerException if the specified collection is null
3.316 + */
3.317 + public boolean retainAll(Collection<?> c) {
3.318 + if (!(c instanceof JumboEnumSet))
3.319 + return super.retainAll(c);
3.320 +
3.321 + JumboEnumSet<?> es = (JumboEnumSet<?>)c;
3.322 + if (es.elementType != elementType) {
3.323 + boolean changed = (size != 0);
3.324 + clear();
3.325 + return changed;
3.326 + }
3.327 +
3.328 + for (int i = 0; i < elements.length; i++)
3.329 + elements[i] &= es.elements[i];
3.330 + return recalculateSize();
3.331 + }
3.332 +
3.333 + /**
3.334 + * Removes all of the elements from this set.
3.335 + */
3.336 + public void clear() {
3.337 + Arrays.fill(elements, 0);
3.338 + size = 0;
3.339 + }
3.340 +
3.341 + /**
3.342 + * Compares the specified object with this set for equality. Returns
3.343 + * <tt>true</tt> if the given object is also a set, the two sets have
3.344 + * the same size, and every member of the given set is contained in
3.345 + * this set.
3.346 + *
3.347 + * @param e object to be compared for equality with this set
3.348 + * @return <tt>true</tt> if the specified object is equal to this set
3.349 + */
3.350 + public boolean equals(Object o) {
3.351 + if (!(o instanceof JumboEnumSet))
3.352 + return super.equals(o);
3.353 +
3.354 + JumboEnumSet es = (JumboEnumSet)o;
3.355 + if (es.elementType != elementType)
3.356 + return size == 0 && es.size == 0;
3.357 +
3.358 + return Arrays.equals(es.elements, elements);
3.359 + }
3.360 +
3.361 + /**
3.362 + * Recalculates the size of the set. Returns true if it's changed.
3.363 + */
3.364 + private boolean recalculateSize() {
3.365 + int oldSize = size;
3.366 + size = 0;
3.367 + for (long elt : elements)
3.368 + size += Long.bitCount(elt);
3.369 +
3.370 + return size != oldSize;
3.371 + }
3.372 +
3.373 + public EnumSet<E> clone() {
3.374 + JumboEnumSet<E> result = (JumboEnumSet<E>) super.clone();
3.375 + result.elements = result.elements.clone();
3.376 + return result;
3.377 + }
3.378 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/emul/compact/src/main/java/java/util/RegularEnumSet.java Sun Sep 22 21:49:42 2013 +0200
4.3 @@ -0,0 +1,303 @@
4.4 +/*
4.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4.7 + *
4.8 + * This code is free software; you can redistribute it and/or modify it
4.9 + * under the terms of the GNU General Public License version 2 only, as
4.10 + * published by the Free Software Foundation. Oracle designates this
4.11 + * particular file as subject to the "Classpath" exception as provided
4.12 + * by Oracle in the LICENSE file that accompanied this code.
4.13 + *
4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4.17 + * version 2 for more details (a copy is included in the LICENSE file that
4.18 + * accompanied this code).
4.19 + *
4.20 + * You should have received a copy of the GNU General Public License version
4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4.23 + *
4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4.25 + * or visit www.oracle.com if you need additional information or have any
4.26 + * questions.
4.27 + */
4.28 +
4.29 +package java.util;
4.30 +
4.31 +/**
4.32 + * Private implementation class for EnumSet, for "regular sized" enum types
4.33 + * (i.e., those with 64 or fewer enum constants).
4.34 + *
4.35 + * @author Josh Bloch
4.36 + * @since 1.5
4.37 + * @serial exclude
4.38 + */
4.39 +class RegularEnumSet<E extends Enum<E>> extends EnumSet<E> {
4.40 + private static final long serialVersionUID = 3411599620347842686L;
4.41 + /**
4.42 + * Bit vector representation of this set. The 2^k bit indicates the
4.43 + * presence of universe[k] in this set.
4.44 + */
4.45 + private long elements = 0L;
4.46 +
4.47 + RegularEnumSet(Class<E>elementType, Enum[] universe) {
4.48 + super(elementType, universe);
4.49 + }
4.50 +
4.51 + void addRange(E from, E to) {
4.52 + elements = (-1L >>> (from.ordinal() - to.ordinal() - 1)) << from.ordinal();
4.53 + }
4.54 +
4.55 + void addAll() {
4.56 + if (universe.length != 0)
4.57 + elements = -1L >>> -universe.length;
4.58 + }
4.59 +
4.60 + void complement() {
4.61 + if (universe.length != 0) {
4.62 + elements = ~elements;
4.63 + elements &= -1L >>> -universe.length; // Mask unused bits
4.64 + }
4.65 + }
4.66 +
4.67 + /**
4.68 + * Returns an iterator over the elements contained in this set. The
4.69 + * iterator traverses the elements in their <i>natural order</i> (which is
4.70 + * the order in which the enum constants are declared). The returned
4.71 + * Iterator is a "snapshot" iterator that will never throw {@link
4.72 + * ConcurrentModificationException}; the elements are traversed as they
4.73 + * existed when this call was invoked.
4.74 + *
4.75 + * @return an iterator over the elements contained in this set
4.76 + */
4.77 + public Iterator<E> iterator() {
4.78 + return new EnumSetIterator<>();
4.79 + }
4.80 +
4.81 + private class EnumSetIterator<E extends Enum<E>> implements Iterator<E> {
4.82 + /**
4.83 + * A bit vector representing the elements in the set not yet
4.84 + * returned by this iterator.
4.85 + */
4.86 + long unseen;
4.87 +
4.88 + /**
4.89 + * The bit representing the last element returned by this iterator
4.90 + * but not removed, or zero if no such element exists.
4.91 + */
4.92 + long lastReturned = 0;
4.93 +
4.94 + EnumSetIterator() {
4.95 + unseen = elements;
4.96 + }
4.97 +
4.98 + public boolean hasNext() {
4.99 + return unseen != 0;
4.100 + }
4.101 +
4.102 + public E next() {
4.103 + if (unseen == 0)
4.104 + throw new NoSuchElementException();
4.105 + lastReturned = unseen & -unseen;
4.106 + unseen -= lastReturned;
4.107 + return (E) universe[Long.numberOfTrailingZeros(lastReturned)];
4.108 + }
4.109 +
4.110 + public void remove() {
4.111 + if (lastReturned == 0)
4.112 + throw new IllegalStateException();
4.113 + elements &= ~lastReturned;
4.114 + lastReturned = 0;
4.115 + }
4.116 + }
4.117 +
4.118 + /**
4.119 + * Returns the number of elements in this set.
4.120 + *
4.121 + * @return the number of elements in this set
4.122 + */
4.123 + public int size() {
4.124 + return Long.bitCount(elements);
4.125 + }
4.126 +
4.127 + /**
4.128 + * Returns <tt>true</tt> if this set contains no elements.
4.129 + *
4.130 + * @return <tt>true</tt> if this set contains no elements
4.131 + */
4.132 + public boolean isEmpty() {
4.133 + return elements == 0;
4.134 + }
4.135 +
4.136 + /**
4.137 + * Returns <tt>true</tt> if this set contains the specified element.
4.138 + *
4.139 + * @param e element to be checked for containment in this collection
4.140 + * @return <tt>true</tt> if this set contains the specified element
4.141 + */
4.142 + public boolean contains(Object e) {
4.143 + if (e == null)
4.144 + return false;
4.145 + Class eClass = e.getClass();
4.146 + if (eClass != elementType && eClass.getSuperclass() != elementType)
4.147 + return false;
4.148 +
4.149 + return (elements & (1L << ((Enum)e).ordinal())) != 0;
4.150 + }
4.151 +
4.152 + // Modification Operations
4.153 +
4.154 + /**
4.155 + * Adds the specified element to this set if it is not already present.
4.156 + *
4.157 + * @param e element to be added to this set
4.158 + * @return <tt>true</tt> if the set changed as a result of the call
4.159 + *
4.160 + * @throws NullPointerException if <tt>e</tt> is null
4.161 + */
4.162 + public boolean add(E e) {
4.163 + typeCheck(e);
4.164 +
4.165 + long oldElements = elements;
4.166 + elements |= (1L << ((Enum)e).ordinal());
4.167 + return elements != oldElements;
4.168 + }
4.169 +
4.170 + /**
4.171 + * Removes the specified element from this set if it is present.
4.172 + *
4.173 + * @param e element to be removed from this set, if present
4.174 + * @return <tt>true</tt> if the set contained the specified element
4.175 + */
4.176 + public boolean remove(Object e) {
4.177 + if (e == null)
4.178 + return false;
4.179 + Class eClass = e.getClass();
4.180 + if (eClass != elementType && eClass.getSuperclass() != elementType)
4.181 + return false;
4.182 +
4.183 + long oldElements = elements;
4.184 + elements &= ~(1L << ((Enum)e).ordinal());
4.185 + return elements != oldElements;
4.186 + }
4.187 +
4.188 + // Bulk Operations
4.189 +
4.190 + /**
4.191 + * Returns <tt>true</tt> if this set contains all of the elements
4.192 + * in the specified collection.
4.193 + *
4.194 + * @param c collection to be checked for containment in this set
4.195 + * @return <tt>true</tt> if this set contains all of the elements
4.196 + * in the specified collection
4.197 + * @throws NullPointerException if the specified collection is null
4.198 + */
4.199 + public boolean containsAll(Collection<?> c) {
4.200 + if (!(c instanceof RegularEnumSet))
4.201 + return super.containsAll(c);
4.202 +
4.203 + RegularEnumSet es = (RegularEnumSet)c;
4.204 + if (es.elementType != elementType)
4.205 + return es.isEmpty();
4.206 +
4.207 + return (es.elements & ~elements) == 0;
4.208 + }
4.209 +
4.210 + /**
4.211 + * Adds all of the elements in the specified collection to this set.
4.212 + *
4.213 + * @param c collection whose elements are to be added to this set
4.214 + * @return <tt>true</tt> if this set changed as a result of the call
4.215 + * @throws NullPointerException if the specified collection or any
4.216 + * of its elements are null
4.217 + */
4.218 + public boolean addAll(Collection<? extends E> c) {
4.219 + if (!(c instanceof RegularEnumSet))
4.220 + return super.addAll(c);
4.221 +
4.222 + RegularEnumSet es = (RegularEnumSet)c;
4.223 + if (es.elementType != elementType) {
4.224 + if (es.isEmpty())
4.225 + return false;
4.226 + else
4.227 + throw new ClassCastException(
4.228 + es.elementType + " != " + elementType);
4.229 + }
4.230 +
4.231 + long oldElements = elements;
4.232 + elements |= es.elements;
4.233 + return elements != oldElements;
4.234 + }
4.235 +
4.236 + /**
4.237 + * Removes from this set all of its elements that are contained in
4.238 + * the specified collection.
4.239 + *
4.240 + * @param c elements to be removed from this set
4.241 + * @return <tt>true</tt> if this set changed as a result of the call
4.242 + * @throws NullPointerException if the specified collection is null
4.243 + */
4.244 + public boolean removeAll(Collection<?> c) {
4.245 + if (!(c instanceof RegularEnumSet))
4.246 + return super.removeAll(c);
4.247 +
4.248 + RegularEnumSet es = (RegularEnumSet)c;
4.249 + if (es.elementType != elementType)
4.250 + return false;
4.251 +
4.252 + long oldElements = elements;
4.253 + elements &= ~es.elements;
4.254 + return elements != oldElements;
4.255 + }
4.256 +
4.257 + /**
4.258 + * Retains only the elements in this set that are contained in the
4.259 + * specified collection.
4.260 + *
4.261 + * @param c elements to be retained in this set
4.262 + * @return <tt>true</tt> if this set changed as a result of the call
4.263 + * @throws NullPointerException if the specified collection is null
4.264 + */
4.265 + public boolean retainAll(Collection<?> c) {
4.266 + if (!(c instanceof RegularEnumSet))
4.267 + return super.retainAll(c);
4.268 +
4.269 + RegularEnumSet<?> es = (RegularEnumSet<?>)c;
4.270 + if (es.elementType != elementType) {
4.271 + boolean changed = (elements != 0);
4.272 + elements = 0;
4.273 + return changed;
4.274 + }
4.275 +
4.276 + long oldElements = elements;
4.277 + elements &= es.elements;
4.278 + return elements != oldElements;
4.279 + }
4.280 +
4.281 + /**
4.282 + * Removes all of the elements from this set.
4.283 + */
4.284 + public void clear() {
4.285 + elements = 0;
4.286 + }
4.287 +
4.288 + /**
4.289 + * Compares the specified object with this set for equality. Returns
4.290 + * <tt>true</tt> if the given object is also a set, the two sets have
4.291 + * the same size, and every member of the given set is contained in
4.292 + * this set.
4.293 + *
4.294 + * @param e object to be compared for equality with this set
4.295 + * @return <tt>true</tt> if the specified object is equal to this set
4.296 + */
4.297 + public boolean equals(Object o) {
4.298 + if (!(o instanceof RegularEnumSet))
4.299 + return super.equals(o);
4.300 +
4.301 + RegularEnumSet es = (RegularEnumSet)o;
4.302 + if (es.elementType != elementType)
4.303 + return elements == 0 && es.elements == 0;
4.304 + return es.elements == elements;
4.305 + }
4.306 +}