1 7 8 package java.util; 9 10 18 class JumboEnumSet<E extends Enum <E>> extends EnumSet <E> { 19 24 private long elements[]; 25 26 private int size = 0; 28 29 JumboEnumSet(Class <E>elementType, Enum [] universe) { 30 super(elementType, universe); 31 elements = new long[(universe.length + 63) >>> 6]; 32 } 33 34 void addRange(E from, E to) { 35 int fromIndex = from.ordinal() >>> 6; 36 int toIndex = to.ordinal() >>> 6; 37 38 if (fromIndex == toIndex) { 39 elements[fromIndex] = (-1L >>> (from.ordinal() - to.ordinal() - 1)) 40 << from.ordinal(); 41 } else { 42 elements[fromIndex] = (-1L << from.ordinal()); 43 for (int i = fromIndex + 1; i < toIndex; i++) 44 elements[i] = -1; 45 elements[toIndex] = -1L >>> (63 - to.ordinal()); 46 } 47 size = to.ordinal() - from.ordinal() + 1; 48 } 49 50 void addAll() { 51 for (int i = 0; i < elements.length; i++) 52 elements[i] = -1; 53 elements[elements.length - 1] >>>= -universe.length; 54 size = universe.length; 55 } 56 57 void complement() { 58 for (int i = 0; i < elements.length; i++) 59 elements[i] = ~elements[i]; 60 elements[elements.length - 1] &= (-1L >>> -universe.length); 61 size = universe.length - size; 62 } 63 64 73 public Iterator <E> iterator() { 74 return new EnumSetIterator<E>(); 75 } 76 77 private class EnumSetIterator<E extends Enum <E>> implements Iterator <E> { 78 82 long unseen; 83 84 87 int unseenIndex = 0; 88 89 93 long lastReturned = 0; 94 95 98 int lastReturnedIndex = 0; 99 100 EnumSetIterator() { 101 unseen = elements[0]; 102 } 103 104 public boolean hasNext() { 105 while (unseen == 0 && unseenIndex < elements.length - 1) 106 unseen = elements[++unseenIndex]; 107 return unseen != 0; 108 } 109 110 public E next() { 111 if (!hasNext()) 112 throw new NoSuchElementException (); 113 lastReturned = unseen & -unseen; 114 lastReturnedIndex = unseenIndex; 115 unseen -= lastReturned; 116 return (E) universe[(lastReturnedIndex << 6) 117 + Long.numberOfTrailingZeros(lastReturned)]; 118 } 119 120 public void remove() { 121 if (lastReturned == 0) 122 throw new IllegalStateException (); 123 elements[lastReturnedIndex] -= lastReturned; 124 size--; 125 lastReturned = 0; 126 } 127 } 128 129 134 public int size() { 135 return size; 136 } 137 138 143 public boolean isEmpty() { 144 return size == 0; 145 } 146 147 153 public boolean contains(Object e) { 154 if (e == null) 155 return false; 156 Class eClass = e.getClass(); 157 if (eClass != elementType && eClass.getSuperclass() != elementType) 158 return false; 159 160 int eOrdinal = ((Enum )e).ordinal(); 161 return (elements[eOrdinal >>> 6] & (1L << eOrdinal)) != 0; 162 } 163 164 166 174 public boolean add(E e) { 175 typeCheck(e); 176 177 int eOrdinal = e.ordinal(); 178 int eWordNum = eOrdinal >>> 6; 179 180 long oldElements = elements[eWordNum]; 181 elements[eWordNum] |= (1L << eOrdinal); 182 boolean result = (elements[eWordNum] != oldElements); 183 if (result) 184 size++; 185 return result; 186 } 187 188 194 public boolean remove(Object e) { 195 if (e == null) 196 return false; 197 Class eClass = e.getClass(); 198 if (eClass != elementType && eClass.getSuperclass() != elementType) 199 return false; 200 int eOrdinal = ((Enum )e).ordinal(); 201 int eWordNum = eOrdinal >>> 6; 202 203 long oldElements = elements[eWordNum]; 204 elements[eWordNum] &= ~(1L << eOrdinal); 205 boolean result = (elements[eWordNum] != oldElements); 206 if (result) 207 size--; 208 return result; 209 } 210 211 213 222 public boolean containsAll(Collection <?> c) { 223 if (!(c instanceof JumboEnumSet )) 224 return super.containsAll(c); 225 226 JumboEnumSet es = (JumboEnumSet )c; 227 if (es.elementType != elementType) 228 return es.isEmpty(); 229 230 for (int i = 0; i < elements.length; i++) 231 if ((es.elements[i] & ~elements[i]) != 0) 232 return false; 233 return true; 234 } 235 236 244 public boolean addAll(Collection <? extends E> c) { 245 if (!(c instanceof JumboEnumSet )) 246 return super.addAll(c); 247 248 JumboEnumSet es = (JumboEnumSet )c; 249 if (es.elementType != elementType) { 250 if (es.isEmpty()) 251 return false; 252 else 253 throw new ClassCastException ( 254 es.elementType + " != " + elementType); 255 } 256 257 for (int i = 0; i < elements.length; i++) 258 elements[i] |= es.elements[i]; 259 return recalculateSize(); 260 } 261 262 270 public boolean removeAll(Collection <?> c) { 271 if (!(c instanceof JumboEnumSet )) 272 return super.removeAll(c); 273 274 JumboEnumSet es = (JumboEnumSet )c; 275 if (es.elementType != elementType) 276 return false; 277 278 for (int i = 0; i < elements.length; i++) 279 elements[i] &= ~es.elements[i]; 280 return recalculateSize(); 281 } 282 283 291 public boolean retainAll(Collection <?> c) { 292 if (!(c instanceof JumboEnumSet )) 293 return super.retainAll(c); 294 295 JumboEnumSet es = (JumboEnumSet )c; 296 if (es.elementType != elementType) { 297 clear(); 298 return true; 299 } 300 301 for (int i = 0; i < elements.length; i++) 302 elements[i] &= es.elements[i]; 303 return recalculateSize(); 304 } 305 306 309 public void clear() { 310 Arrays.fill(elements, 0); 311 size = 0; 312 } 313 314 323 public boolean equals(Object o) { 324 if (!(o instanceof JumboEnumSet )) 325 return super.equals(o); 326 327 JumboEnumSet es = (JumboEnumSet )o; 328 if (es.elementType != elementType) 329 return size == 0 && es.size == 0; 330 331 return Arrays.equals(es.elements, elements); 332 } 333 334 337 private boolean recalculateSize() { 338 int oldSize = size; 339 size = 0; 340 for (long elt : elements) 341 size += Long.bitCount(elt); 342 343 return size != oldSize; 344 } 345 346 public EnumSet <E> clone() { 347 JumboEnumSet <E> result = (JumboEnumSet <E>) super.clone(); 348 result.elements = (long[]) result.elements.clone(); 349 return result; 350 } 351 } 352 | Popular Tags |