/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.util;
Private implementation class for EnumSet, for "regular sized" enum types
(i.e., those with 64 or fewer enum constants).
Author: Josh Bloch Since: 1.5 @serial exclude
/**
* Private implementation class for EnumSet, for "regular sized" enum types
* (i.e., those with 64 or fewer enum constants).
*
* @author Josh Bloch
* @since 1.5
* @serial exclude
*/
class RegularEnumSet<E extends Enum<E>> extends EnumSet<E> {
private static final long serialVersionUID = 3411599620347842686L;
Bit vector representation of this set. The 2^k bit indicates the
presence of universe[k] in this set.
/**
* Bit vector representation of this set. The 2^k bit indicates the
* presence of universe[k] in this set.
*/
private long elements = 0L;
RegularEnumSet(Class<E>elementType, Enum<?>[] universe) {
super(elementType, universe);
}
void addRange(E from, E to) {
elements = (-1L >>> (from.ordinal() - to.ordinal() - 1)) << from.ordinal();
}
void addAll() {
if (universe.length != 0)
elements = -1L >>> -universe.length;
}
void complement() {
if (universe.length != 0) {
elements = ~elements;
elements &= -1L >>> -universe.length; // Mask unused bits
}
}
Returns an iterator over the elements contained in this set. The
iterator traverses the elements in their natural order (which is the order in which the enum constants are declared). The returned Iterator is a "snapshot" iterator that will never throw ConcurrentModificationException
; the elements are traversed as they existed when this call was invoked. Returns: an iterator over the elements contained in this set
/**
* Returns an iterator over the elements contained in this set. The
* iterator traverses the elements in their <i>natural order</i> (which is
* the order in which the enum constants are declared). The returned
* Iterator is a "snapshot" iterator that will never throw {@link
* ConcurrentModificationException}; the elements are traversed as they
* existed when this call was invoked.
*
* @return an iterator over the elements contained in this set
*/
public Iterator<E> iterator() {
return new EnumSetIterator<>();
}
private class EnumSetIterator<E extends Enum<E>> implements Iterator<E> {
A bit vector representing the elements in the set not yet
returned by this iterator.
/**
* A bit vector representing the elements in the set not yet
* returned by this iterator.
*/
long unseen;
The bit representing the last element returned by this iterator
but not removed, or zero if no such element exists.
/**
* The bit representing the last element returned by this iterator
* but not removed, or zero if no such element exists.
*/
long lastReturned = 0;
EnumSetIterator() {
unseen = elements;
}
public boolean hasNext() {
return unseen != 0;
}
@SuppressWarnings("unchecked")
public E next() {
if (unseen == 0)
throw new NoSuchElementException();
lastReturned = unseen & -unseen;
unseen -= lastReturned;
return (E) universe[Long.numberOfTrailingZeros(lastReturned)];
}
public void remove() {
if (lastReturned == 0)
throw new IllegalStateException();
elements &= ~lastReturned;
lastReturned = 0;
}
}
Returns the number of elements in this set.
Returns: the number of elements in this set
/**
* Returns the number of elements in this set.
*
* @return the number of elements in this set
*/
public int size() {
return Long.bitCount(elements);
}
Returns true
if this set contains no elements. Returns: true
if this set contains no elements
/**
* Returns {@code true} if this set contains no elements.
*
* @return {@code true} if this set contains no elements
*/
public boolean isEmpty() {
return elements == 0;
}
Returns true
if this set contains the specified element. Params: - e – element to be checked for containment in this collection
Returns: true
if this set contains the specified element
/**
* Returns {@code true} if this set contains the specified element.
*
* @param e element to be checked for containment in this collection
* @return {@code true} if this set contains the specified element
*/
public boolean contains(Object e) {
if (e == null)
return false;
Class<?> eClass = e.getClass();
if (eClass != elementType && eClass.getSuperclass() != elementType)
return false;
return (elements & (1L << ((Enum<?>)e).ordinal())) != 0;
}
// Modification Operations
Adds the specified element to this set if it is not already present.
Params: - e – element to be added to this set
Throws: - NullPointerException – if
e
is null
Returns: true
if the set changed as a result of the call
/**
* Adds the specified element to this set if it is not already present.
*
* @param e element to be added to this set
* @return {@code true} if the set changed as a result of the call
*
* @throws NullPointerException if {@code e} is null
*/
public boolean add(E e) {
typeCheck(e);
long oldElements = elements;
elements |= (1L << ((Enum<?>)e).ordinal());
return elements != oldElements;
}
Removes the specified element from this set if it is present.
Params: - e – element to be removed from this set, if present
Returns: true
if the set contained the specified element
/**
* Removes the specified element from this set if it is present.
*
* @param e element to be removed from this set, if present
* @return {@code true} if the set contained the specified element
*/
public boolean remove(Object e) {
if (e == null)
return false;
Class<?> eClass = e.getClass();
if (eClass != elementType && eClass.getSuperclass() != elementType)
return false;
long oldElements = elements;
elements &= ~(1L << ((Enum<?>)e).ordinal());
return elements != oldElements;
}
// Bulk Operations
Returns true
if this set contains all of the elements in the specified collection. Params: - c – collection to be checked for containment in this set
Throws: - NullPointerException – if the specified collection is null
Returns: true
if this set contains all of the elements in the specified collection
/**
* Returns {@code true} if this set contains all of the elements
* in the specified collection.
*
* @param c collection to be checked for containment in this set
* @return {@code true} if this set contains all of the elements
* in the specified collection
* @throws NullPointerException if the specified collection is null
*/
public boolean containsAll(Collection<?> c) {
if (!(c instanceof RegularEnumSet))
return super.containsAll(c);
RegularEnumSet<?> es = (RegularEnumSet<?>)c;
if (es.elementType != elementType)
return es.isEmpty();
return (es.elements & ~elements) == 0;
}
Adds all of the elements in the specified collection to this set.
Params: - c – collection whose elements are to be added to this set
Throws: - NullPointerException – if the specified collection or any
of its elements are null
Returns: true
if this set changed as a result of the call
/**
* Adds all of the elements in the specified collection to this set.
*
* @param c collection whose elements are to be added to this set
* @return {@code true} if this set changed as a result of the call
* @throws NullPointerException if the specified collection or any
* of its elements are null
*/
public boolean addAll(Collection<? extends E> c) {
if (!(c instanceof RegularEnumSet))
return super.addAll(c);
RegularEnumSet<?> es = (RegularEnumSet<?>)c;
if (es.elementType != elementType) {
if (es.isEmpty())
return false;
else
throw new ClassCastException(
es.elementType + " != " + elementType);
}
long oldElements = elements;
elements |= es.elements;
return elements != oldElements;
}
Removes from this set all of its elements that are contained in
the specified collection.
Params: - c – elements to be removed from this set
Throws: - NullPointerException – if the specified collection is null
Returns: true
if this set changed as a result of the call
/**
* Removes from this set all of its elements that are contained in
* the specified collection.
*
* @param c elements to be removed from this set
* @return {@code true} if this set changed as a result of the call
* @throws NullPointerException if the specified collection is null
*/
public boolean removeAll(Collection<?> c) {
if (!(c instanceof RegularEnumSet))
return super.removeAll(c);
RegularEnumSet<?> es = (RegularEnumSet<?>)c;
if (es.elementType != elementType)
return false;
long oldElements = elements;
elements &= ~es.elements;
return elements != oldElements;
}
Retains only the elements in this set that are contained in the
specified collection.
Params: - c – elements to be retained in this set
Throws: - NullPointerException – if the specified collection is null
Returns: true
if this set changed as a result of the call
/**
* Retains only the elements in this set that are contained in the
* specified collection.
*
* @param c elements to be retained in this set
* @return {@code true} if this set changed as a result of the call
* @throws NullPointerException if the specified collection is null
*/
public boolean retainAll(Collection<?> c) {
if (!(c instanceof RegularEnumSet))
return super.retainAll(c);
RegularEnumSet<?> es = (RegularEnumSet<?>)c;
if (es.elementType != elementType) {
boolean changed = (elements != 0);
elements = 0;
return changed;
}
long oldElements = elements;
elements &= es.elements;
return elements != oldElements;
}
Removes all of the elements from this set.
/**
* Removes all of the elements from this set.
*/
public void clear() {
elements = 0;
}
Compares the specified object with this set for equality. Returns true
if the given object is also a set, the two sets have the same size, and every member of the given set is contained in this set. Params: - o – object to be compared for equality with this set
Returns: true
if the specified object is equal to this set
/**
* Compares the specified object with this set for equality. Returns
* {@code true} if the given object is also a set, the two sets have
* the same size, and every member of the given set is contained in
* this set.
*
* @param o object to be compared for equality with this set
* @return {@code true} if the specified object is equal to this set
*/
public boolean equals(Object o) {
if (!(o instanceof RegularEnumSet))
return super.equals(o);
RegularEnumSet<?> es = (RegularEnumSet<?>)o;
if (es.elementType != elementType)
return elements == 0 && es.elements == 0;
return es.elements == elements;
}
}