A concrete EnumSet for enums with more than 64 elements.
Method from java.util.HugeEnumSet Detail: |
public boolean add(E element) {
if (!isValidType(element.getDeclaringClass())) {
throw new ClassCastException();
}
int ordinal = element.ordinal();
int index = ordinal / BIT_IN_LONG;
int inBits = ordinal % BIT_IN_LONG;
long oldBits = bits[index];
long newBits = oldBits | (1L < < inBits);
if (oldBits != newBits) {
bits[index] = newBits;
size++;
return true;
}
return false;
}
|
public boolean addAll(Collection<? extends E> collection) {
if (collection.isEmpty() || collection == this) {
return false;
}
if (collection instanceof EnumSet) {
EnumSet< ? > set = (EnumSet< ? >) collection;
if (!isValidType(set.elementClass)) {
throw new ClassCastException();
}
HugeEnumSet< E > hugeSet = (HugeEnumSet< E >) set;
boolean changed = false;
for (int i = 0; i < bits.length; i++) {
long oldBits = bits[i];
long newBits = oldBits | hugeSet.bits[i];
if (oldBits != newBits) {
bits[i] = newBits;
size += Long.bitCount(newBits) - Long.bitCount(oldBits);
changed = true;
}
}
return changed;
}
return super.addAll(collection);
}
|
public void clear() {
Arrays.fill(bits, 0);
size = 0;
}
|
public HugeEnumSet<E> clone() {
HugeEnumSet< E > set = (HugeEnumSet< E >) super.clone();
set.bits = bits.clone();
return set;
}
|
protected void complement() {
size = 0;
for (int i = 0, length = bits.length; i < length; i++) {
long b = ~bits[i];
// zero out unused bits on the last element
if (i == length - 1) {
b &= -1L > > > (BIT_IN_LONG - (enums.length % BIT_IN_LONG));
}
size += Long.bitCount(b);
bits[i] = b;
}
}
|
public boolean contains(Object object) {
if (object == null || !isValidType(object.getClass())) {
return false;
}
@SuppressWarnings("unchecked") // guarded by isValidType()
int ordinal = ((E) object).ordinal();
int index = ordinal / BIT_IN_LONG;
int inBits = ordinal % BIT_IN_LONG;
return (bits[index] & (1L < < inBits)) != 0;
}
|
public boolean containsAll(Collection<?> collection) {
if (collection.isEmpty()) {
return true;
}
if (collection instanceof HugeEnumSet) {
HugeEnumSet< ? > set = (HugeEnumSet< ? >) collection;
if (isValidType(set.elementClass)) {
for (int i = 0; i < bits.length; i++) {
long setBits = set.bits[i];
if ((bits[i] & setBits) != setBits) {
return false;
}
}
return true;
}
}
return !(collection instanceof EnumSet) && super.containsAll(collection);
}
|
public boolean equals(Object object) {
if (object == null) {
return false;
}
if (!isValidType(object.getClass())) {
return super.equals(object);
}
return Arrays.equals(bits, ((HugeEnumSet< ? >) object).bits);
}
|
public Iterator<E> iterator() {
return new HugeEnumSetIterator();
}
|
public boolean remove(Object object) {
if (object == null || !isValidType(object.getClass())) {
return false;
}
@SuppressWarnings("unchecked") // guarded by isValidType()
int ordinal = ((E) object).ordinal();
int index = ordinal / BIT_IN_LONG;
int inBits = ordinal % BIT_IN_LONG;
long oldBits = bits[index];
long newBits = oldBits & ~(1L < < inBits);
if (oldBits != newBits) {
bits[index] = newBits;
size--;
return true;
}
return false;
}
|
public boolean removeAll(Collection<?> collection) {
if (collection.isEmpty()) {
return false;
}
if (collection instanceof EnumSet) {
EnumSet< ? > set = (EnumSet< ? >) collection;
if (!isValidType(set.elementClass)) {
return false;
}
HugeEnumSet< E > hugeSet = (HugeEnumSet< E >) set;
boolean changed = false;
for (int i = 0; i < bits.length; i++) {
long oldBits = bits[i];
long newBits = oldBits & ~hugeSet.bits[i];
if (oldBits != newBits) {
bits[i] = newBits;
size += Long.bitCount(newBits) - Long.bitCount(oldBits);
changed = true;
}
}
return changed;
}
return super.removeAll(collection);
}
|
public boolean retainAll(Collection<?> collection) {
if (collection instanceof EnumSet) {
EnumSet< ? > set = (EnumSet< ? >) collection;
if (!isValidType(set.elementClass)) {
if (size > 0) {
clear();
return true;
} else {
return false;
}
}
HugeEnumSet< E > hugeSet = (HugeEnumSet< E >) set;
boolean changed = false;
for (int i = 0; i < bits.length; i++) {
long oldBits = bits[i];
long newBits = oldBits & hugeSet.bits[i];
if (oldBits != newBits) {
bits[i] = newBits;
size += Long.bitCount(newBits) - Long.bitCount(oldBits);
changed = true;
}
}
return changed;
}
return super.retainAll(collection);
}
|
void setRange(E start,
E end) {
int startOrdinal = start.ordinal();
int startIndex = startOrdinal / BIT_IN_LONG;
int startInBits = startOrdinal % BIT_IN_LONG;
int endOrdinal = end.ordinal();
int endIndex = endOrdinal / BIT_IN_LONG;
int endInBits = endOrdinal % BIT_IN_LONG;
if (startIndex == endIndex) {
long range = (-1L > > > (BIT_IN_LONG -(endInBits - startInBits + 1))) < < startInBits;
size -= Long.bitCount(bits[startIndex]);
bits[startIndex] |= range;
size += Long.bitCount(bits[startIndex]);
} else {
long range = (-1L > > > startInBits) < < startInBits;
size -= Long.bitCount(bits[startIndex]);
bits[startIndex] |= range;
size += Long.bitCount(bits[startIndex]);
// endInBits + 1 is the number of consecutive ones.
// 63 - endInBits is the following zeros of the right most one.
range = -1L > > > (BIT_IN_LONG - (endInBits + 1));
size -= Long.bitCount(bits[endIndex]);
bits[endIndex] |= range;
size += Long.bitCount(bits[endIndex]);
for (int i = (startIndex + 1); i < = (endIndex - 1); i++) {
size -= Long.bitCount(bits[i]);
bits[i] = -1L;
size += Long.bitCount(bits[i]);
}
}
}
|
public int size() {
return size;
}
|