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