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