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