mirror of
https://github.com/corda/corda.git
synced 2025-06-13 04:38:19 +00:00
Adding EnumSet, which is backed by a speedy BitSet.
This commit is contained in:
149
classpath/java/util/EnumSet.java
Normal file
149
classpath/java/util/EnumSet.java
Normal file
@ -0,0 +1,149 @@
|
||||
package java.util;
|
||||
|
||||
public class EnumSet<T extends Enum<T>> extends AbstractSet<T> {
|
||||
|
||||
private BitSet bitset;
|
||||
private Class<T> elementType;
|
||||
|
||||
private EnumSet(int size, Class<T> type) {
|
||||
bitset = new BitSet(size);
|
||||
elementType = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(T element) {
|
||||
int index = element.ordinal();
|
||||
boolean contains = bitset.get(index);
|
||||
if (!contains) {
|
||||
bitset.set(index);
|
||||
}
|
||||
|
||||
return !contains;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object toRemove) {
|
||||
T element = tryToCast(toRemove);
|
||||
|
||||
int index = element.ordinal();
|
||||
boolean contains = bitset.get(index);
|
||||
if (contains) {
|
||||
bitset.clear(index);
|
||||
}
|
||||
|
||||
return contains;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object toCheck) {
|
||||
T element = tryToCast(toCheck);
|
||||
int index = element.ordinal();
|
||||
return bitset.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return bitset.cardinality();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new EnumSetIterator();
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> allOf(Class<T> elementType) {
|
||||
EnumSet<T> enumSet = createEmptyEnumSet(elementType);
|
||||
addAllElementsToSet(Arrays.asList(elementType.getEnumConstants()), enumSet);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> noneOf(Class<T> elementType) {
|
||||
return createEmptyEnumSet(elementType);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> of(T first, T ... rest) {
|
||||
EnumSet<T> enumSet = createEmptyEnumSet(first.getDeclaringClass());
|
||||
enumSet.add(first);
|
||||
addAllElementsToSet(Arrays.asList(rest), enumSet);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> complementOf(EnumSet<T> s) {
|
||||
EnumSet<T> enumSet = copyOf(s);
|
||||
enumSet.bitset.flip(0, s.elementType.getEnumConstants().length);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> copyOf(EnumSet<T> s) {
|
||||
EnumSet<T> enumSet = createEmptyEnumSet(s.elementType);
|
||||
enumSet.bitset.or(s.bitset);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
private static <T extends Enum<T>>EnumSet<T> createEmptyEnumSet(Class<T> elementType) {
|
||||
T[] constants = elementType.getEnumConstants();
|
||||
EnumSet<T> enumSet = new EnumSet<T>(constants.length, elementType);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
private static <T extends Enum<T>> void addAllElementsToSet(Iterable<T> elements, EnumSet<T> enumSet) {
|
||||
for (T element : elements) {
|
||||
enumSet.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T tryToCast(Object object) throws ClassCastException {
|
||||
//We want the class cast exception if we can't convert.
|
||||
return (T) object;
|
||||
}
|
||||
|
||||
private class EnumSetIterator implements Iterator<T> {
|
||||
private int currentIndex = 0;
|
||||
private boolean removeAllowed = false;
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException("EnumSet has no more elements");
|
||||
}
|
||||
|
||||
int indexOfNextValue = nextIndex();
|
||||
T element = elementType.getEnumConstants()[indexOfNextValue];
|
||||
currentIndex = indexOfNextValue + 1;
|
||||
removeAllowed = true;
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
int indexOfNextValue = nextIndex();
|
||||
if (indexOfNextValue >= 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
//TODO
|
||||
if (!removeAllowed) {
|
||||
throw new IllegalStateException("Cannot remove from this iterator in this state");
|
||||
}
|
||||
|
||||
bitset.clear(currentIndex - 1);
|
||||
removeAllowed = false;
|
||||
}
|
||||
|
||||
private int nextIndex() {
|
||||
return bitset.nextSetBit(currentIndex);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user