001 /* 002 * Copyright (C) 2007 Google Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package com.google.common.collect; 018 019 import static com.google.common.base.Preconditions.checkArgument; 020 import static com.google.common.base.Preconditions.checkNotNull; 021 022 import com.google.common.annotations.GwtCompatible; 023 024 import java.io.Serializable; 025 import java.util.ArrayList; 026 import java.util.Collection; 027 import java.util.Collections; 028 import java.util.HashSet; 029 import java.util.Iterator; 030 import java.util.Set; 031 032 import javax.annotation.Nullable; 033 034 /** 035 * A high-performance, immutable {@code Set} with reliable, user-specified 036 * iteration order. Does not permit null elements. 037 * 038 * <p>Unlike {@link Collections#unmodifiableSet}, which is a <i>view</i> of a 039 * separate collection that can still change, an instance of this class contains 040 * its own private data and will <i>never</i> change. This class is convenient 041 * for {@code public static final} sets ("constant sets") and also lets you 042 * easily make a "defensive copy" of a set provided to your class by a caller. 043 * 044 * <p><b>Warning:</b> Like most sets, an {@code ImmutableSet} will not function 045 * correctly if an element is modified after being placed in the set. For this 046 * reason, and to avoid general confusion, it is strongly recommended to place 047 * only immutable objects into this collection. 048 * 049 * <p>This class has been observed to perform significantly better than {@link 050 * HashSet} for objects with very fast {@link Object#hashCode} implementations 051 * (as a well-behaved immutable object should). While this class's factory 052 * methods create hash-based instances, the {@link ImmutableSortedSet} subclass 053 * performs binary searches instead. 054 * 055 * <p><b>Note</b>: Although this class is not final, it cannot be subclassed 056 * outside its package as it has no public or protected constructors. Thus, 057 * instances of this type are guaranteed to be immutable. 058 * 059 * @see ImmutableList 060 * @see ImmutableMap 061 * @author Kevin Bourrillion 062 * @author Nick Kralevich 063 * @since 2 (imported from Google Collections Library) 064 */ 065 @GwtCompatible(serializable = true, emulated = true) 066 @SuppressWarnings("serial") // we're overriding default serialization 067 public abstract class ImmutableSet<E> extends ImmutableCollection<E> 068 implements Set<E> { 069 /** 070 * Returns the empty immutable set. This set behaves and performs comparably 071 * to {@link Collections#emptySet}, and is preferable mainly for consistency 072 * and maintainability of your code. 073 */ 074 // Casting to any type is safe because the set will never hold any elements. 075 @SuppressWarnings({"unchecked"}) 076 public static <E> ImmutableSet<E> of() { 077 return (ImmutableSet<E>) EmptyImmutableSet.INSTANCE; 078 } 079 080 /** 081 * Returns an immutable set containing a single element. This set behaves and 082 * performs comparably to {@link Collections#singleton}, but will not accept 083 * a null element. It is preferable mainly for consistency and 084 * maintainability of your code. 085 */ 086 public static <E> ImmutableSet<E> of(E element) { 087 return new SingletonImmutableSet<E>(element); 088 } 089 090 /** 091 * Returns an immutable set containing the given elements, in order. Repeated 092 * occurrences of an element (according to {@link Object#equals}) after the 093 * first are ignored. 094 * 095 * @throws NullPointerException if any element is null 096 */ 097 public static <E> ImmutableSet<E> of(E e1, E e2) { 098 return construct(e1, e2); 099 } 100 101 /** 102 * Returns an immutable set containing the given elements, in order. Repeated 103 * occurrences of an element (according to {@link Object#equals}) after the 104 * first are ignored. 105 * 106 * @throws NullPointerException if any element is null 107 */ 108 public static <E> ImmutableSet<E> of(E e1, E e2, E e3) { 109 return construct(e1, e2, e3); 110 } 111 112 /** 113 * Returns an immutable set containing the given elements, in order. Repeated 114 * occurrences of an element (according to {@link Object#equals}) after the 115 * first are ignored. 116 * 117 * @throws NullPointerException if any element is null 118 */ 119 public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4) { 120 return construct(e1, e2, e3, e4); 121 } 122 123 /** 124 * Returns an immutable set containing the given elements, in order. Repeated 125 * occurrences of an element (according to {@link Object#equals}) after the 126 * first are ignored. 127 * 128 * @throws NullPointerException if any element is null 129 */ 130 public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5) { 131 return construct(e1, e2, e3, e4, e5); 132 } 133 134 /** 135 * Returns an immutable set containing the given elements, in order. Repeated 136 * occurrences of an element (according to {@link Object#equals}) after the 137 * first are ignored. 138 * 139 * @throws NullPointerException if any element is null 140 * @since 3 (source-compatible since release 2) 141 */ 142 public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, 143 E... others) { 144 final int paramCount = 6; 145 Object[] elements = new Object[paramCount + others.length]; 146 elements[0] = e1; 147 elements[1] = e2; 148 elements[2] = e3; 149 elements[3] = e4; 150 elements[4] = e5; 151 elements[5] = e6; 152 for (int i = paramCount; i < elements.length; i++) { 153 elements[i] = others[i - paramCount]; 154 } 155 return construct(elements); 156 } 157 158 /** {@code elements} has to be internally created array. */ 159 private static <E> ImmutableSet<E> construct(Object... elements) { 160 int tableSize = chooseTableSize(elements.length); 161 Object[] table = new Object[tableSize]; 162 int mask = tableSize - 1; 163 ArrayList<Object> uniqueElementsList = null; 164 int hashCode = 0; 165 for (int i = 0; i < elements.length; i++) { 166 Object element = elements[i]; 167 int hash = element.hashCode(); 168 for (int j = Hashing.smear(hash); ; j++) { 169 int index = j & mask; 170 Object value = table[index]; 171 if (value == null) { 172 if (uniqueElementsList != null) { 173 uniqueElementsList.add(element); 174 } 175 // Came to an empty slot. Put the element here. 176 table[index] = element; 177 hashCode += hash; 178 break; 179 } else if (value.equals(element)) { 180 if (uniqueElementsList == null) { 181 // first dup 182 uniqueElementsList = new ArrayList<Object>(elements.length); 183 for (int k = 0; k < i; k++) { 184 Object previous = elements[k]; 185 uniqueElementsList.add(previous); 186 } 187 } 188 break; 189 } 190 } 191 } 192 Object[] uniqueElements = uniqueElementsList == null 193 ? elements 194 : uniqueElementsList.toArray(); 195 if (uniqueElements.length == 1) { 196 // There is only one element or elements are all duplicates 197 @SuppressWarnings("unchecked") // we are careful to only pass in E 198 E element = (E) uniqueElements[0]; 199 return new SingletonImmutableSet<E>(element, hashCode); 200 } else if (tableSize > 2 * chooseTableSize(uniqueElements.length)) { 201 // Resize the table when the array includes too many duplicates. 202 // when this happens, we have already made a copy 203 return construct(uniqueElements); 204 } else { 205 return new RegularImmutableSet<E>(uniqueElements, hashCode, table, mask); 206 } 207 } 208 209 // We use power-of-2 tables, and this is the highest int that's a power of 2 210 static final int MAX_TABLE_SIZE = 1 << 30; 211 212 // If the set has this many elements, it will "max out" the table size 213 static final int CUTOFF = 1 << 29; 214 215 /** 216 * Returns an array size suitable for the backing array of a hash table that 217 * uses linear probing in its implementation. The returned size is the 218 * smallest power of two that can hold setSize elements while being at most 219 * 50% full, if possible. 220 */ 221 static int chooseTableSize(int setSize) { 222 if (setSize < CUTOFF) { 223 return Integer.highestOneBit(setSize) << 2; 224 } 225 226 // The table can't be completely full or we'll get infinite reprobes 227 checkArgument(setSize < MAX_TABLE_SIZE, "collection too large"); 228 return MAX_TABLE_SIZE; 229 } 230 231 /** 232 * Returns an immutable set containing the given elements, in order. Repeated 233 * occurrences of an element (according to {@link Object#equals}) after the 234 * first are ignored. 235 * 236 * @deprecated use {@link #copyOf(Object[])}. <b>This method is scheduled for 237 * deletion in October 2011.</b> 238 * @throws NullPointerException if any of {@code elements} is null 239 * @since 2 (changed from varargs in release 3) 240 */ 241 // TODO(kevinb): when this is removed, remember to remove from ISS and ISSFS 242 @Deprecated 243 public static <E> ImmutableSet<E> of(E[] elements) { 244 return copyOf(elements); 245 } 246 247 /** 248 * Returns an immutable set containing the given elements, in order. Repeated 249 * occurrences of an element (according to {@link Object#equals}) after the 250 * first are ignored. 251 * 252 * @throws NullPointerException if any of {@code elements} is null 253 * @since 3 254 */ 255 public static <E> ImmutableSet<E> copyOf(E[] elements) { 256 // TODO(benyu): could we delegate to 257 // copyFromCollection(Arrays.asList(elements))? 258 switch (elements.length) { 259 case 0: 260 return of(); 261 case 1: 262 return of(elements[0]); 263 default: 264 return construct(elements.clone()); 265 } 266 } 267 268 /** 269 * Returns an immutable set containing the given elements, in order. Repeated 270 * occurrences of an element (according to {@link Object#equals}) after the 271 * first are ignored. This method iterates over {@code elements} at most once. 272 * 273 * <p>Note that if {@code s} is a {@code Set<String>}, then {@code 274 * ImmutableSet.copyOf(s)} returns an {@code ImmutableSet<String>} containing 275 * each of the strings in {@code s}, while {@code ImmutableSet.of(s)} returns 276 * a {@code ImmutableSet<Set<String>>} containing one element (the given set 277 * itself). 278 * 279 * <p>Despite the method name, this method attempts to avoid actually copying 280 * the data when it is safe to do so. The exact circumstances under which a 281 * copy will or will not be performed are undocumented and subject to change. 282 * 283 * @throws NullPointerException if any of {@code elements} is null 284 */ 285 public static <E> ImmutableSet<E> copyOf(Iterable<? extends E> elements) { 286 return (elements instanceof Collection) 287 ? copyOf(Collections2.cast(elements)) 288 : copyOf(elements.iterator()); 289 } 290 291 /** 292 * Returns an immutable set containing the given elements, in order. Repeated 293 * occurrences of an element (according to {@link Object#equals}) after the 294 * first are ignored. 295 * 296 * @throws NullPointerException if any of {@code elements} is null 297 */ 298 public static <E> ImmutableSet<E> copyOf(Iterator<? extends E> elements) { 299 // TODO(benyu): here we could avoid toArray() for 0 or 1-element list, 300 // worth it? 301 return copyFromCollection(Lists.newArrayList(elements)); 302 } 303 304 /** 305 * Returns an immutable set containing the given elements, in order. Repeated 306 * occurrences of an element (according to {@link Object#equals}) after the 307 * first are ignored. This method iterates over {@code elements} at most 308 * once. 309 * 310 * <p>Note that if {@code s} is a {@code Set<String>}, then {@code 311 * ImmutableSet.copyOf(s)} returns an {@code ImmutableSet<String>} containing 312 * each of the strings in {@code s}, while {@code ImmutableSet.of(s)} returns 313 * a {@code ImmutableSet<Set<String>>} containing one element (the given set 314 * itself). 315 * 316 * <p><b>Note:</b> Despite what the method name suggests, {@code copyOf} will 317 * return constant-space views, rather than linear-space copies, of some 318 * inputs known to be immutable. For some other immutable inputs, such as key 319 * sets of an {@code ImmutableMap}, it still performs a copy in order to avoid 320 * holding references to the values of the map. The heuristics used in this 321 * decision are undocumented and subject to change except that: 322 * <ul> 323 * <li>A full copy will be done of any {@code ImmutableSortedSet}.</li> 324 * <li>{@code ImmutableSet.copyOf()} is idempotent with respect to pointer 325 * equality.</li> 326 * </ul> 327 * 328 * <p>This method is safe to use even when {@code elements} is a synchronized 329 * or concurrent collection that is currently being modified by another 330 * thread. 331 * 332 * @throws NullPointerException if any of {@code elements} is null 333 * @since 7 (source-compatible since release 2) 334 */ 335 public static <E> ImmutableSet<E> copyOf(Collection<? extends E> elements) { 336 if (elements instanceof ImmutableSet 337 && !(elements instanceof ImmutableSortedSet)) { 338 @SuppressWarnings("unchecked") // all supported methods are covariant 339 ImmutableSet<E> set = (ImmutableSet<E>) elements; 340 if (!set.isPartialView()) { 341 return set; 342 } 343 } 344 return copyFromCollection(elements); 345 } 346 347 private static <E> ImmutableSet<E> copyFromCollection( 348 Collection<? extends E> collection) { 349 Object[] elements = collection.toArray(); 350 switch (elements.length) { 351 case 0: 352 return of(); 353 case 1: 354 @SuppressWarnings("unchecked") // collection had only Es in it 355 E onlyElement = (E) elements[0]; 356 return of(onlyElement); 357 default: 358 // safe to use the array without copying it 359 // as specified by Collection.toArray(). 360 return construct(elements); 361 } 362 } 363 364 ImmutableSet() {} 365 366 /** Returns {@code true} if the {@code hashCode()} method runs quickly. */ 367 boolean isHashCodeFast() { 368 return false; 369 } 370 371 @Override public boolean equals(@Nullable Object object) { 372 if (object == this) { 373 return true; 374 } 375 if (object instanceof ImmutableSet 376 && isHashCodeFast() 377 && ((ImmutableSet<?>) object).isHashCodeFast() 378 && hashCode() != object.hashCode()) { 379 return false; 380 } 381 return Sets.equalsImpl(this, object); 382 } 383 384 @Override public int hashCode() { 385 return Sets.hashCodeImpl(this); 386 } 387 388 // This declaration is needed to make Set.iterator() and 389 // ImmutableCollection.iterator() consistent. 390 @Override public abstract UnmodifiableIterator<E> iterator(); 391 392 abstract static class ArrayImmutableSet<E> extends ImmutableSet<E> { 393 // the elements (two or more) in the desired order. 394 final transient Object[] elements; 395 396 ArrayImmutableSet(Object[] elements) { 397 this.elements = elements; 398 } 399 400 public int size() { 401 return elements.length; 402 } 403 404 @Override public boolean isEmpty() { 405 return false; 406 } 407 408 /* 409 * The cast is safe because the only way to create an instance is via the 410 * create() method above, which only permits elements of type E. 411 */ 412 @SuppressWarnings("unchecked") 413 @Override public UnmodifiableIterator<E> iterator() { 414 return (UnmodifiableIterator<E>) Iterators.forArray(elements); 415 } 416 417 @Override public Object[] toArray() { 418 Object[] array = new Object[size()]; 419 System.arraycopy(elements, 0, array, 0, size()); 420 return array; 421 } 422 423 @Override public <T> T[] toArray(T[] array) { 424 int size = size(); 425 if (array.length < size) { 426 array = ObjectArrays.newArray(array, size); 427 } else if (array.length > size) { 428 array[size] = null; 429 } 430 System.arraycopy(elements, 0, array, 0, size); 431 return array; 432 } 433 434 @Override public boolean containsAll(Collection<?> targets) { 435 if (targets == this) { 436 return true; 437 } 438 if (!(targets instanceof ArrayImmutableSet)) { 439 return super.containsAll(targets); 440 } 441 if (targets.size() > size()) { 442 return false; 443 } 444 for (Object target : ((ArrayImmutableSet<?>) targets).elements) { 445 if (!contains(target)) { 446 return false; 447 } 448 } 449 return true; 450 } 451 452 @Override boolean isPartialView() { 453 return false; 454 } 455 456 @Override ImmutableList<E> createAsList() { 457 return new ImmutableAsList<E>(elements, this); 458 } 459 } 460 461 /** such as ImmutableMap.keySet() */ 462 abstract static class TransformedImmutableSet<D, E> extends ImmutableSet<E> { 463 final D[] source; 464 final int hashCode; 465 466 TransformedImmutableSet(D[] source, int hashCode) { 467 this.source = source; 468 this.hashCode = hashCode; 469 } 470 471 abstract E transform(D element); 472 473 public int size() { 474 return source.length; 475 } 476 477 @Override public boolean isEmpty() { 478 return false; 479 } 480 481 @Override public UnmodifiableIterator<E> iterator() { 482 return new AbstractIndexedListIterator<E>(source.length) { 483 @Override protected E get(int index) { 484 return transform(source[index]); 485 } 486 }; 487 } 488 489 @Override public Object[] toArray() { 490 return toArray(new Object[size()]); 491 } 492 493 @Override public <T> T[] toArray(T[] array) { 494 int size = size(); 495 if (array.length < size) { 496 array = ObjectArrays.newArray(array, size); 497 } else if (array.length > size) { 498 array[size] = null; 499 } 500 501 // Writes will produce ArrayStoreException when the toArray() doc requires 502 Object[] objectArray = array; 503 for (int i = 0; i < source.length; i++) { 504 objectArray[i] = transform(source[i]); 505 } 506 return array; 507 } 508 509 @Override public final int hashCode() { 510 return hashCode; 511 } 512 513 @Override boolean isHashCodeFast() { 514 return true; 515 } 516 } 517 518 /* 519 * This class is used to serialize all ImmutableSet instances, except for 520 * ImmutableEnumSet/ImmutableSortedSet, regardless of implementation type. It 521 * captures their "logical contents" and they are reconstructed using public 522 * static factories. This is necessary to ensure that the existence of a 523 * particular implementation type is an implementation detail. 524 */ 525 private static class SerializedForm implements Serializable { 526 final Object[] elements; 527 SerializedForm(Object[] elements) { 528 this.elements = elements; 529 } 530 Object readResolve() { 531 return copyOf(elements); 532 } 533 private static final long serialVersionUID = 0; 534 } 535 536 @Override Object writeReplace() { 537 return new SerializedForm(toArray()); 538 } 539 540 /** 541 * Returns a new builder. The generated builder is equivalent to the builder 542 * created by the {@link Builder} constructor. 543 */ 544 public static <E> Builder<E> builder() { 545 return new Builder<E>(); 546 } 547 548 /** 549 * A builder for creating immutable set instances, especially {@code public 550 * static final} sets ("constant sets"). Example: <pre> {@code 551 * 552 * public static final ImmutableSet<Color> GOOGLE_COLORS = 553 * new ImmutableSet.Builder<Color>() 554 * .addAll(WEBSAFE_COLORS) 555 * .add(new Color(0, 191, 255)) 556 * .build();}</pre> 557 * 558 * Builder instances can be reused; it is safe to call {@link #build} multiple 559 * times to build multiple sets in series. Each set is a superset of the set 560 * created before it. 561 * 562 * @since 2 (imported from Google Collections Library) 563 */ 564 public static class Builder<E> extends ImmutableCollection.Builder<E> { 565 // accessed directly by ImmutableSortedSet 566 final ArrayList<E> contents = Lists.newArrayList(); 567 568 /** 569 * Creates a new builder. The returned builder is equivalent to the builder 570 * generated by {@link ImmutableSet#builder}. 571 */ 572 public Builder() {} 573 574 /** 575 * Adds {@code element} to the {@code ImmutableSet}. If the {@code 576 * ImmutableSet} already contains {@code element}, then {@code add} has no 577 * effect (only the previously added element is retained). 578 * 579 * @param element the element to add 580 * @return this {@code Builder} object 581 * @throws NullPointerException if {@code element} is null 582 */ 583 @Override public Builder<E> add(E element) { 584 contents.add(checkNotNull(element)); 585 return this; 586 } 587 588 /** 589 * Adds each element of {@code elements} to the {@code ImmutableSet}, 590 * ignoring duplicate elements (only the first duplicate element is added). 591 * 592 * @param elements the elements to add 593 * @return this {@code Builder} object 594 * @throws NullPointerException if {@code elements} is null or contains a 595 * null element 596 */ 597 @Override public Builder<E> add(E... elements) { 598 contents.ensureCapacity(contents.size() + elements.length); 599 super.add(elements); 600 return this; 601 } 602 603 /** 604 * Adds each element of {@code elements} to the {@code ImmutableSet}, 605 * ignoring duplicate elements (only the first duplicate element is added). 606 * 607 * @param elements the {@code Iterable} to add to the {@code ImmutableSet} 608 * @return this {@code Builder} object 609 * @throws NullPointerException if {@code elements} is null or contains a 610 * null element 611 */ 612 @Override public Builder<E> addAll(Iterable<? extends E> elements) { 613 if (elements instanceof Collection) { 614 Collection<?> collection = (Collection<?>) elements; 615 contents.ensureCapacity(contents.size() + collection.size()); 616 } 617 super.addAll(elements); 618 return this; 619 } 620 621 /** 622 * Adds each element of {@code elements} to the {@code ImmutableSet}, 623 * ignoring duplicate elements (only the first duplicate element is added). 624 * 625 * @param elements the elements to add to the {@code ImmutableSet} 626 * @return this {@code Builder} object 627 * @throws NullPointerException if {@code elements} is null or contains a 628 * null element 629 */ 630 @Override public Builder<E> addAll(Iterator<? extends E> elements) { 631 super.addAll(elements); 632 return this; 633 } 634 635 /** 636 * Returns a newly-created {@code ImmutableSet} based on the contents of 637 * the {@code Builder}. 638 */ 639 @Override public ImmutableSet<E> build() { 640 return copyOf(contents); 641 } 642 } 643 }