package java.util; public class EnumSet> extends AbstractSet { private BitSet bitset; private Class elementType; private EnumSet(int size, Class 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 iterator() { return new EnumSetIterator(); } public static >EnumSet allOf(Class elementType) { EnumSet enumSet = createEmptyEnumSet(elementType); enumSet.bitset.set(0, elementType.getEnumConstants().length); return enumSet; } public static >EnumSet noneOf(Class elementType) { return createEmptyEnumSet(elementType); } public static >EnumSet of(T first, T ... rest) { EnumSet enumSet = createEmptyEnumSet(first.getDeclaringClass()); enumSet.add(first); addAllElementsToSet(Arrays.asList(rest), enumSet); return enumSet; } public static >EnumSet complementOf(EnumSet s) { EnumSet enumSet = copyOf(s); enumSet.bitset.flip(0, s.elementType.getEnumConstants().length); return enumSet; } public static >EnumSet copyOf(EnumSet s) { EnumSet enumSet = createEmptyEnumSet(s.elementType); enumSet.bitset.or(s.bitset); return enumSet; } private static >EnumSet createEmptyEnumSet(Class elementType) { T[] constants = elementType.getEnumConstants(); EnumSet enumSet = new EnumSet(constants.length, elementType); return enumSet; } private static > void addAllElementsToSet(Iterable elements, EnumSet 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 { private int currentIndex = 0; private boolean removeAllowed = false; 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; } public boolean hasNext() { int indexOfNextValue = nextIndex(); if (indexOfNextValue >= 0) { return true; } else { return false; } } public void remove() { 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); } } }