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 017package com.google.common.collect; 018 019import static com.google.common.base.Preconditions.checkArgument; 020import static com.google.common.collect.ObjectArrays.checkElementNotNull; 021 022import com.google.common.annotations.GwtCompatible; 023import com.google.common.annotations.VisibleForTesting; 024import com.google.common.primitives.Ints; 025import com.google.errorprone.annotations.CanIgnoreReturnValue; 026import java.io.Serializable; 027import java.util.Arrays; 028import java.util.Collection; 029import java.util.Collections; 030import java.util.EnumSet; 031import java.util.Iterator; 032import java.util.Set; 033import javax.annotation.Nullable; 034 035/** 036 * A {@link Set} whose contents will never change, with many other important properties detailed at 037 * {@link ImmutableCollection}. 038 * 039 * @since 2.0 040 */ 041@GwtCompatible(serializable = true, emulated = true) 042@SuppressWarnings("serial") // we're overriding default serialization 043public abstract class ImmutableSet<E> extends ImmutableCollection<E> implements Set<E> { 044 /** 045 * Returns the empty immutable set. Preferred over {@link Collections#emptySet} for code 046 * consistency, and because the return type conveys the immutability guarantee. 047 */ 048 @SuppressWarnings({"unchecked"}) // fully variant implementation (never actually produces any Es) 049 public static <E> ImmutableSet<E> of() { 050 return (ImmutableSet<E>) RegularImmutableSet.EMPTY; 051 } 052 053 /** 054 * Returns an immutable set containing {@code element}. Preferred over {@link 055 * Collections#singleton} for code consistency, {@code null} rejection, and because the return 056 * type conveys the immutability guarantee. 057 */ 058 public static <E> ImmutableSet<E> of(E element) { 059 return new SingletonImmutableSet<E>(element); 060 } 061 062 /** 063 * Returns an immutable set containing the given elements, minus duplicates, in the order each was 064 * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except 065 * the first are ignored. 066 */ 067 public static <E> ImmutableSet<E> of(E e1, E e2) { 068 return construct(2, e1, e2); 069 } 070 071 /** 072 * Returns an immutable set containing the given elements, minus duplicates, in the order each was 073 * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except 074 * the first are ignored. 075 */ 076 public static <E> ImmutableSet<E> of(E e1, E e2, E e3) { 077 return construct(3, e1, e2, e3); 078 } 079 080 /** 081 * Returns an immutable set containing the given elements, minus duplicates, in the order each was 082 * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except 083 * the first are ignored. 084 */ 085 public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4) { 086 return construct(4, e1, e2, e3, e4); 087 } 088 089 /** 090 * Returns an immutable set containing the given elements, minus duplicates, in the order each was 091 * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except 092 * the first are ignored. 093 */ 094 public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5) { 095 return construct(5, e1, e2, e3, e4, e5); 096 } 097 098 /** 099 * Returns an immutable set containing the given elements, minus duplicates, in the order each was 100 * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except 101 * the first are ignored. 102 * 103 * @since 3.0 (source-compatible since 2.0) 104 */ 105 @SafeVarargs // For Eclipse. For internal javac we have disabled this pointless type of warning. 106 public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E... others) { 107 final int paramCount = 6; 108 Object[] elements = new Object[paramCount + others.length]; 109 elements[0] = e1; 110 elements[1] = e2; 111 elements[2] = e3; 112 elements[3] = e4; 113 elements[4] = e5; 114 elements[5] = e6; 115 System.arraycopy(others, 0, elements, paramCount, others.length); 116 return construct(elements.length, elements); 117 } 118 119 /** 120 * Constructs an {@code ImmutableSet} from the first {@code n} elements of the specified array. 121 * If {@code k} is the size of the returned {@code ImmutableSet}, then the unique elements of 122 * {@code elements} will be in the first {@code k} positions, and {@code elements[i] == null} for 123 * {@code k <= i < n}. 124 * 125 * <p>This may modify {@code elements}. Additionally, if {@code n == elements.length} and 126 * {@code elements} contains no duplicates, {@code elements} may be used without copying in the 127 * returned {@code ImmutableSet}, in which case it may no longer be modified. 128 * 129 * <p>{@code elements} may contain only values of type {@code E}. 130 * 131 * @throws NullPointerException if any of the first {@code n} elements of {@code elements} is 132 * null 133 */ 134 private static <E> ImmutableSet<E> construct(int n, Object... elements) { 135 switch (n) { 136 case 0: 137 return of(); 138 case 1: 139 @SuppressWarnings("unchecked") // safe; elements contains only E's 140 E elem = (E) elements[0]; 141 return of(elem); 142 default: 143 // continue below to handle the general case 144 } 145 int tableSize = chooseTableSize(n); 146 Object[] table = new Object[tableSize]; 147 int mask = tableSize - 1; 148 int hashCode = 0; 149 int uniques = 0; 150 for (int i = 0; i < n; i++) { 151 Object element = checkElementNotNull(elements[i], i); 152 int hash = element.hashCode(); 153 for (int j = Hashing.smear(hash); ; j++) { 154 int index = j & mask; 155 Object value = table[index]; 156 if (value == null) { 157 // Came to an empty slot. Put the element here. 158 elements[uniques++] = element; 159 table[index] = element; 160 hashCode += hash; 161 break; 162 } else if (value.equals(element)) { 163 break; 164 } 165 } 166 } 167 Arrays.fill(elements, uniques, n, null); 168 if (uniques == 1) { 169 // There is only one element or elements are all duplicates 170 @SuppressWarnings("unchecked") // we are careful to only pass in E 171 E element = (E) elements[0]; 172 return new SingletonImmutableSet<E>(element, hashCode); 173 } else if (tableSize != chooseTableSize(uniques)) { 174 // Resize the table when the array includes too many duplicates. 175 // when this happens, we have already made a copy 176 return construct(uniques, elements); 177 } else { 178 Object[] uniqueElements = 179 (uniques < elements.length) ? ObjectArrays.arraysCopyOf(elements, uniques) : elements; 180 return new RegularImmutableSet<E>(uniqueElements, hashCode, table, mask); 181 } 182 } 183 184 // We use power-of-2 tables, and this is the highest int that's a power of 2 185 static final int MAX_TABLE_SIZE = Ints.MAX_POWER_OF_TWO; 186 187 // Represents how tightly we can pack things, as a maximum. 188 private static final double DESIRED_LOAD_FACTOR = 0.7; 189 190 // If the set has this many elements, it will "max out" the table size 191 private static final int CUTOFF = (int) (MAX_TABLE_SIZE * DESIRED_LOAD_FACTOR); 192 193 /** 194 * Returns an array size suitable for the backing array of a hash table that 195 * uses open addressing with linear probing in its implementation. The 196 * returned size is the smallest power of two that can hold setSize elements 197 * with the desired load factor. 198 * 199 * <p>Do not call this method with setSize < 2. 200 */ 201 @VisibleForTesting 202 static int chooseTableSize(int setSize) { 203 // Correct the size for open addressing to match desired load factor. 204 if (setSize < CUTOFF) { 205 // Round up to the next highest power of 2. 206 int tableSize = Integer.highestOneBit(setSize - 1) << 1; 207 while (tableSize * DESIRED_LOAD_FACTOR < setSize) { 208 tableSize <<= 1; 209 } 210 return tableSize; 211 } 212 213 // The table can't be completely full or we'll get infinite reprobes 214 checkArgument(setSize < MAX_TABLE_SIZE, "collection too large"); 215 return MAX_TABLE_SIZE; 216 } 217 218 /** 219 * Returns an immutable set containing each of {@code elements}, minus duplicates, in the order 220 * each appears first in the source collection. 221 * 222 * <p><b>Performance note:</b> This method will sometimes recognize that the actual copy operation 223 * is unnecessary; for example, {@code copyOf(copyOf(anArrayList))} will copy the data only once. 224 * This reduces the expense of habitually making defensive copies at API boundaries. However, the 225 * precise conditions for skipping the copy operation are undefined. 226 * 227 * @throws NullPointerException if any of {@code elements} is null 228 * @since 7.0 (source-compatible since 2.0) 229 */ 230 public static <E> ImmutableSet<E> copyOf(Collection<? extends E> elements) { 231 /* 232 * TODO(lowasser): consider checking for ImmutableAsList here 233 * TODO(lowasser): consider checking for Multiset here 234 */ 235 if (elements instanceof ImmutableSet && !(elements instanceof ImmutableSortedSet)) { 236 @SuppressWarnings("unchecked") // all supported methods are covariant 237 ImmutableSet<E> set = (ImmutableSet<E>) elements; 238 if (!set.isPartialView()) { 239 return set; 240 } 241 } else if (elements instanceof EnumSet) { 242 return copyOfEnumSet((EnumSet) elements); 243 } 244 Object[] array = elements.toArray(); 245 return construct(array.length, array); 246 } 247 248 /** 249 * Returns an immutable set containing each of {@code elements}, minus duplicates, in the order 250 * each appears first in the source iterable. This method iterates over {@code elements} only 251 * once. 252 * 253 * <p><b>Performance note:</b> This method will sometimes recognize that the actual copy operation 254 * is unnecessary; for example, {@code copyOf(copyOf(anArrayList))} should copy the data only 255 * once. This reduces the expense of habitually making defensive copies at API boundaries. 256 * However, the precise conditions for skipping the copy operation are undefined. 257 * 258 * @throws NullPointerException if any of {@code elements} is null 259 */ 260 public static <E> ImmutableSet<E> copyOf(Iterable<? extends E> elements) { 261 return (elements instanceof Collection) 262 ? copyOf((Collection<? extends E>) elements) 263 : copyOf(elements.iterator()); 264 } 265 266 /** 267 * Returns an immutable set containing each of {@code elements}, minus duplicates, in the order 268 * each appears first in the source iterator. 269 * 270 * @throws NullPointerException if any of {@code elements} is null 271 */ 272 public static <E> ImmutableSet<E> copyOf(Iterator<? extends E> elements) { 273 // We special-case for 0 or 1 elements, but anything further is madness. 274 if (!elements.hasNext()) { 275 return of(); 276 } 277 E first = elements.next(); 278 if (!elements.hasNext()) { 279 return of(first); 280 } else { 281 return new ImmutableSet.Builder<E>().add(first).addAll(elements).build(); 282 } 283 } 284 285 /** 286 * Returns an immutable set containing each of {@code elements}, minus duplicates, in the order 287 * each appears first in the source array. 288 * 289 * @throws NullPointerException if any of {@code elements} is null 290 * @since 3.0 291 */ 292 public static <E> ImmutableSet<E> copyOf(E[] elements) { 293 switch (elements.length) { 294 case 0: 295 return of(); 296 case 1: 297 return of(elements[0]); 298 default: 299 return construct(elements.length, elements.clone()); 300 } 301 } 302 303 @SuppressWarnings("rawtypes") // necessary to compile against Java 8 304 private static ImmutableSet copyOfEnumSet(EnumSet enumSet) { 305 return ImmutableEnumSet.asImmutable(EnumSet.copyOf(enumSet)); 306 } 307 308 ImmutableSet() {} 309 310 /** Returns {@code true} if the {@code hashCode()} method runs quickly. */ 311 boolean isHashCodeFast() { 312 return false; 313 } 314 315 @Override 316 public boolean equals(@Nullable Object object) { 317 if (object == this) { 318 return true; 319 } else if (object instanceof ImmutableSet 320 && isHashCodeFast() 321 && ((ImmutableSet<?>) object).isHashCodeFast() 322 && hashCode() != object.hashCode()) { 323 return false; 324 } 325 return Sets.equalsImpl(this, object); 326 } 327 328 @Override 329 public int hashCode() { 330 return Sets.hashCodeImpl(this); 331 } 332 333 // This declaration is needed to make Set.iterator() and 334 // ImmutableCollection.iterator() consistent. 335 @Override 336 public abstract UnmodifiableIterator<E> iterator(); 337 338 private transient ImmutableList<E> asList; 339 340 @Override 341 public ImmutableList<E> asList() { 342 ImmutableList<E> result = asList; 343 return (result == null) ? asList = createAsList() : result; 344 } 345 346 ImmutableList<E> createAsList() { 347 return new RegularImmutableAsList<E>(this, toArray()); 348 } 349 350 abstract static class Indexed<E> extends ImmutableSet<E> { 351 abstract E get(int index); 352 353 @Override 354 public UnmodifiableIterator<E> iterator() { 355 return asList().iterator(); 356 } 357 358 @Override 359 ImmutableList<E> createAsList() { 360 return new ImmutableAsList<E>() { 361 @Override 362 public E get(int index) { 363 return Indexed.this.get(index); 364 } 365 366 @Override 367 Indexed<E> delegateCollection() { 368 return Indexed.this; 369 } 370 }; 371 } 372 } 373 374 /* 375 * This class is used to serialize all ImmutableSet instances, except for 376 * ImmutableEnumSet/ImmutableSortedSet, regardless of implementation type. It 377 * captures their "logical contents" and they are reconstructed using public 378 * static factories. This is necessary to ensure that the existence of a 379 * particular implementation type is an implementation detail. 380 */ 381 private static class SerializedForm implements Serializable { 382 final Object[] elements; 383 384 SerializedForm(Object[] elements) { 385 this.elements = elements; 386 } 387 388 Object readResolve() { 389 return copyOf(elements); 390 } 391 392 private static final long serialVersionUID = 0; 393 } 394 395 @Override 396 Object writeReplace() { 397 return new SerializedForm(toArray()); 398 } 399 400 /** 401 * Returns a new builder. The generated builder is equivalent to the builder 402 * created by the {@link Builder} constructor. 403 */ 404 public static <E> Builder<E> builder() { 405 return new Builder<E>(); 406 } 407 408 /** 409 * A builder for creating {@code ImmutableSet} instances. Example: <pre> {@code 410 * 411 * static final ImmutableSet<Color> GOOGLE_COLORS = 412 * ImmutableSet.<Color>builder() 413 * .addAll(WEBSAFE_COLORS) 414 * .add(new Color(0, 191, 255)) 415 * .build();}</pre> 416 * 417 * <p>Building does not change the state of the builder, so it is still possible to add more 418 * elements and to build again. 419 * 420 * @since 2.0 421 */ 422 public static class Builder<E> extends ImmutableCollection.ArrayBasedBuilder<E> { 423 424 /** 425 * Creates a new builder. The returned builder is equivalent to the builder 426 * generated by {@link ImmutableSet#builder}. 427 */ 428 public Builder() { 429 this(DEFAULT_INITIAL_CAPACITY); 430 } 431 432 Builder(int capacity) { 433 super(capacity); 434 } 435 436 /** 437 * Adds {@code element} to the {@code ImmutableSet}. If the {@code 438 * ImmutableSet} already contains {@code element}, then {@code add} has no 439 * effect (only the previously added element is retained). 440 * 441 * @param element the element to add 442 * @return this {@code Builder} object 443 * @throws NullPointerException if {@code element} is null 444 */ 445 @CanIgnoreReturnValue 446 @Override 447 public Builder<E> add(E element) { 448 super.add(element); 449 return this; 450 } 451 452 /** 453 * Adds each element of {@code elements} to the {@code ImmutableSet}, 454 * ignoring duplicate elements (only the first duplicate element is added). 455 * 456 * @param elements the elements to add 457 * @return this {@code Builder} object 458 * @throws NullPointerException if {@code elements} is null or contains a 459 * null element 460 */ 461 @CanIgnoreReturnValue 462 @Override 463 public Builder<E> add(E... elements) { 464 super.add(elements); 465 return this; 466 } 467 468 /** 469 * Adds each element of {@code elements} to the {@code ImmutableSet}, 470 * ignoring duplicate elements (only the first duplicate element is added). 471 * 472 * @param elements the {@code Iterable} to add to the {@code ImmutableSet} 473 * @return this {@code Builder} object 474 * @throws NullPointerException if {@code elements} is null or contains a 475 * null element 476 */ 477 @CanIgnoreReturnValue 478 @Override 479 public Builder<E> addAll(Iterable<? extends E> elements) { 480 super.addAll(elements); 481 return this; 482 } 483 484 /** 485 * Adds each element of {@code elements} to the {@code ImmutableSet}, 486 * ignoring duplicate elements (only the first duplicate element is added). 487 * 488 * @param elements the elements to add to the {@code ImmutableSet} 489 * @return this {@code Builder} object 490 * @throws NullPointerException if {@code elements} is null or contains a 491 * null element 492 */ 493 @CanIgnoreReturnValue 494 @Override 495 public Builder<E> addAll(Iterator<? extends E> elements) { 496 super.addAll(elements); 497 return this; 498 } 499 500 /** 501 * Returns a newly-created {@code ImmutableSet} based on the contents of 502 * the {@code Builder}. 503 */ 504 @Override 505 public ImmutableSet<E> build() { 506 ImmutableSet<E> result = construct(size, contents); 507 // construct has the side effect of deduping contents, so we update size 508 // accordingly. 509 size = result.size(); 510 return result; 511 } 512 } 513}