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