001/*
002 * Copyright (C) 2008 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 com.google.common.annotations.GwtCompatible;
020import com.google.common.annotations.VisibleForTesting;
021
022import java.io.Serializable;
023import java.util.Collection;
024import java.util.Iterator;
025
026import javax.annotation.Nullable;
027
028/**
029 * An immutable collection. Does not permit null elements.
030 *
031 * <p>In addition to the {@link Collection} methods, this class has an {@link
032 * #asList()} method, which returns a list view of the collection's elements.
033 *
034 * <p><b>Note:</b> Although this class is not final, it cannot be subclassed
035 * outside of this package as it has no public or protected constructors. Thus,
036 * instances of this type are guaranteed to be immutable.
037 *
038 * @author Jesse Wilson
039 * @since 2.0 (imported from Google Collections Library)
040 */
041@GwtCompatible(emulated = true)
042@SuppressWarnings("serial") // we're overriding default serialization
043public abstract class ImmutableCollection<E>
044    implements Collection<E>, Serializable {
045  static final ImmutableCollection<Object> EMPTY_IMMUTABLE_COLLECTION
046      = new EmptyImmutableCollection();
047
048  ImmutableCollection() {}
049
050  /**
051   * Returns an unmodifiable iterator across the elements in this collection.
052   */
053  @Override
054  public abstract UnmodifiableIterator<E> iterator();
055
056  @Override
057  public Object[] toArray() {
058    return ObjectArrays.toArrayImpl(this);
059  }
060
061  @Override
062  public <T> T[] toArray(T[] other) {
063    return ObjectArrays.toArrayImpl(this, other);
064  }
065
066  @Override
067  public boolean contains(@Nullable Object object) {
068    return object != null && Iterators.contains(iterator(), object);
069  }
070
071  @Override
072  public boolean containsAll(Collection<?> targets) {
073    return Collections2.containsAllImpl(this, targets);
074  }
075
076  @Override
077  public boolean isEmpty() {
078    return size() == 0;
079  }
080
081  @Override public String toString() {
082    return Collections2.toStringImpl(this);
083  }
084
085  /**
086   * Guaranteed to throw an exception and leave the collection unmodified.
087   *
088   * @throws UnsupportedOperationException always
089   * @deprecated Unsupported operation.
090   */
091  @Deprecated
092  @Override
093  public final boolean add(E e) {
094    throw new UnsupportedOperationException();
095  }
096
097  /**
098   * Guaranteed to throw an exception and leave the collection unmodified.
099   *
100   * @throws UnsupportedOperationException always
101   * @deprecated Unsupported operation.
102   */
103  @Deprecated
104  @Override
105  public final boolean remove(Object object) {
106    throw new UnsupportedOperationException();
107  }
108
109  /**
110   * Guaranteed to throw an exception and leave the collection unmodified.
111   *
112   * @throws UnsupportedOperationException always
113   * @deprecated Unsupported operation.
114   */
115  @Deprecated
116  @Override
117  public final boolean addAll(Collection<? extends E> newElements) {
118    throw new UnsupportedOperationException();
119  }
120
121  /**
122   * Guaranteed to throw an exception and leave the collection unmodified.
123   *
124   * @throws UnsupportedOperationException always
125   * @deprecated Unsupported operation.
126   */
127  @Deprecated
128  @Override
129  public final boolean removeAll(Collection<?> oldElements) {
130    throw new UnsupportedOperationException();
131  }
132
133  /**
134   * Guaranteed to throw an exception and leave the collection unmodified.
135   *
136   * @throws UnsupportedOperationException always
137   * @deprecated Unsupported operation.
138   */
139  @Deprecated
140  @Override
141  public final boolean retainAll(Collection<?> elementsToKeep) {
142    throw new UnsupportedOperationException();
143  }
144
145  /**
146   * Guaranteed to throw an exception and leave the collection unmodified.
147   *
148   * @throws UnsupportedOperationException always
149   * @deprecated Unsupported operation.
150   */
151  @Deprecated
152  @Override
153  public final void clear() {
154    throw new UnsupportedOperationException();
155  }
156
157  /*
158   * TODO(kevinb): Restructure code so ImmutableList doesn't contain this
159   * variable, which it doesn't use.
160   */
161  private transient ImmutableList<E> asList;
162
163  /**
164   * Returns a list view of the collection.
165   *
166   * @since 2.0
167   */
168  public ImmutableList<E> asList() {
169    ImmutableList<E> list = asList;
170    return (list == null) ? (asList = createAsList()) : list;
171  }
172
173  ImmutableList<E> createAsList() {
174    switch (size()) {
175      case 0:
176        return ImmutableList.of();
177      case 1:
178        return ImmutableList.of(iterator().next());
179      default:
180        return new RegularImmutableAsList<E>(this, toArray());
181    }
182  }
183
184  abstract boolean isPartialView();
185
186  private static class EmptyImmutableCollection
187      extends ImmutableCollection<Object> {
188    @Override
189    public int size() {
190      return 0;
191    }
192
193    @Override public boolean isEmpty() {
194      return true;
195    }
196
197    @Override public boolean contains(@Nullable Object object) {
198      return false;
199    }
200
201    @Override public UnmodifiableIterator<Object> iterator() {
202      return Iterators.EMPTY_LIST_ITERATOR;
203    }
204
205    private static final Object[] EMPTY_ARRAY = new Object[0];
206
207    @Override public Object[] toArray() {
208      return EMPTY_ARRAY;
209    }
210
211    @Override public <T> T[] toArray(T[] array) {
212      if (array.length > 0) {
213        array[0] = null;
214      }
215      return array;
216    }
217
218    @Override ImmutableList<Object> createAsList() {
219      return ImmutableList.of();
220    }
221
222    @Override boolean isPartialView() {
223      return false;
224    }
225  }
226
227  /**
228   * Nonempty collection stored in an array.
229   */
230  private static class ArrayImmutableCollection<E>
231      extends ImmutableCollection<E> {
232    private final E[] elements;
233
234    ArrayImmutableCollection(E[] elements) {
235      this.elements = elements;
236    }
237
238    @Override
239    public int size() {
240      return elements.length;
241    }
242
243    @Override public boolean isEmpty() {
244      return false;
245    }
246
247    @Override public UnmodifiableIterator<E> iterator() {
248      return Iterators.forArray(elements);
249    }
250
251    @Override ImmutableList<E> createAsList() {
252      return elements.length == 1 ? new SingletonImmutableList<E>(elements[0])
253          : new RegularImmutableList<E>(elements);
254    }
255
256    @Override boolean isPartialView() {
257      return false;
258    }
259  }
260
261  /*
262   * Serializes ImmutableCollections as their logical contents. This ensures
263   * that implementation types do not leak into the serialized representation.
264   */
265  private static class SerializedForm implements Serializable {
266    final Object[] elements;
267    SerializedForm(Object[] elements) {
268      this.elements = elements;
269    }
270    Object readResolve() {
271      return elements.length == 0
272          ? EMPTY_IMMUTABLE_COLLECTION
273          : new ArrayImmutableCollection<Object>(Platform.clone(elements));
274    }
275    private static final long serialVersionUID = 0;
276  }
277
278  Object writeReplace() {
279    return new SerializedForm(toArray());
280  }
281
282  /**
283   * Abstract base class for builders of {@link ImmutableCollection} types.
284   *
285   * @since 10.0
286   */
287  public abstract static class Builder<E> {
288    static final int DEFAULT_INITIAL_CAPACITY = 4;
289
290    @VisibleForTesting
291    static int expandedCapacity(int oldCapacity, int minCapacity) {
292      if (minCapacity < 0) {
293        throw new AssertionError("cannot store more than MAX_VALUE elements");
294      }
295      // careful of overflow!
296      int newCapacity = oldCapacity + (oldCapacity >> 1) + 1;
297      if (newCapacity < minCapacity) {
298        newCapacity = Integer.highestOneBit(minCapacity - 1) << 1;
299      }
300      if (newCapacity < 0) {
301        newCapacity = Integer.MAX_VALUE;
302        // guaranteed to be >= newCapacity
303      }
304      return newCapacity;
305    }
306
307    Builder() {
308    }
309
310    /**
311     * Adds {@code element} to the {@code ImmutableCollection} being built.
312     *
313     * <p>Note that each builder class covariantly returns its own type from
314     * this method.
315     *
316     * @param element the element to add
317     * @return this {@code Builder} instance
318     * @throws NullPointerException if {@code element} is null
319     */
320    public abstract Builder<E> add(E element);
321
322    /**
323     * Adds each element of {@code elements} to the {@code ImmutableCollection}
324     * being built.
325     *
326     * <p>Note that each builder class overrides this method in order to
327     * covariantly return its own type.
328     *
329     * @param elements the elements to add
330     * @return this {@code Builder} instance
331     * @throws NullPointerException if {@code elements} is null or contains a
332     *     null element
333     */
334    public Builder<E> add(E... elements) {
335      for (E element : elements) {
336        add(element);
337      }
338      return this;
339    }
340
341    /**
342     * Adds each element of {@code elements} to the {@code ImmutableCollection}
343     * being built.
344     *
345     * <p>Note that each builder class overrides this method in order to
346     * covariantly return its own type.
347     *
348     * @param elements the elements to add
349     * @return this {@code Builder} instance
350     * @throws NullPointerException if {@code elements} is null or contains a
351     *     null element
352     */
353    public Builder<E> addAll(Iterable<? extends E> elements) {
354      for (E element : elements) {
355        add(element);
356      }
357      return this;
358    }
359
360    /**
361     * Adds each element of {@code elements} to the {@code ImmutableCollection}
362     * being built.
363     *
364     * <p>Note that each builder class overrides this method in order to
365     * covariantly return its own type.
366     *
367     * @param elements the elements to add
368     * @return this {@code Builder} instance
369     * @throws NullPointerException if {@code elements} is null or contains a
370     *     null element
371     */
372    public Builder<E> addAll(Iterator<? extends E> elements) {
373      while (elements.hasNext()) {
374        add(elements.next());
375      }
376      return this;
377    }
378
379    /**
380     * Returns a newly-created {@code ImmutableCollection} of the appropriate
381     * type, containing the elements provided to this builder.
382     *
383     * <p>Note that each builder class covariantly returns the appropriate type
384     * of {@code ImmutableCollection} from this method.
385     */
386    public abstract ImmutableCollection<E> build();
387  }
388}