ImmutableList.java revision 1d580d0f6ee4f21eb309ba7b509d2c6d671c4044
1/*
2 * Copyright (C) 2007 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect;
18
19import static com.google.common.base.Preconditions.checkNotNull;
20
21import com.google.common.annotations.GwtCompatible;
22import com.google.common.base.Preconditions;
23
24import java.io.InvalidObjectException;
25import java.io.ObjectInputStream;
26import java.io.Serializable;
27import java.util.ArrayList;
28import java.util.Collection;
29import java.util.Collections;
30import java.util.Iterator;
31import java.util.List;
32import java.util.RandomAccess;
33
34import javax.annotation.Nullable;
35
36/**
37 * A high-performance, immutable, random-access {@code List} implementation.
38 * Does not permit null elements.
39 *
40 * <p>Unlike {@link Collections#unmodifiableList}, which is a <i>view</i> of a
41 * separate collection that can still change, an instance of {@code
42 * ImmutableList} contains its own private data and will <i>never</i> change.
43 * {@code ImmutableList} is convenient for {@code public static final} lists
44 * ("constant lists") and also lets you easily make a "defensive copy" of a list
45 * provided to your class by a caller.
46 *
47 * <p><b>Note:</b> Although this class is not final, it cannot be subclassed as
48 * it has no public or protected constructors. Thus, instances of this type are
49 * guaranteed to be immutable.
50 *
51 * @see ImmutableMap
52 * @see ImmutableSet
53 * @author Kevin Bourrillion
54 * @since 2.0 (imported from Google Collections Library)
55 */
56@GwtCompatible(serializable = true, emulated = true)
57@SuppressWarnings("serial") // we're overriding default serialization
58public abstract class ImmutableList<E> extends ImmutableCollection<E>
59    implements List<E>, RandomAccess {
60  /**
61   * Returns the empty immutable list. This set behaves and performs comparably
62   * to {@link Collections#emptyList}, and is preferable mainly for consistency
63   * and maintainability of your code.
64   */
65  // Casting to any type is safe because the list will never hold any elements.
66  @SuppressWarnings("unchecked")
67  public static <E> ImmutableList<E> of() {
68    return (ImmutableList<E>) EmptyImmutableList.INSTANCE;
69  }
70
71  /**
72   * Returns an immutable list containing a single element. This list behaves
73   * and performs comparably to {@link Collections#singleton}, but will not
74   * accept a null element. It is preferable mainly for consistency and
75   * maintainability of your code.
76   *
77   * @throws NullPointerException if {@code element} is null
78   */
79  public static <E> ImmutableList<E> of(E element) {
80    return new SingletonImmutableList<E>(element);
81  }
82
83  /**
84   * Returns an immutable list containing the given elements, in order.
85   *
86   * @throws NullPointerException if any element is null
87   */
88  public static <E> ImmutableList<E> of(E e1, E e2) {
89    return construct(e1, e2);
90  }
91
92  /**
93   * Returns an immutable list containing the given elements, in order.
94   *
95   * @throws NullPointerException if any element is null
96   */
97  public static <E> ImmutableList<E> of(E e1, E e2, E e3) {
98    return construct(e1, e2, e3);
99  }
100
101  /**
102   * Returns an immutable list containing the given elements, in order.
103   *
104   * @throws NullPointerException if any element is null
105   */
106  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) {
107    return construct(e1, e2, e3, e4);
108  }
109
110  /**
111   * Returns an immutable list containing the given elements, in order.
112   *
113   * @throws NullPointerException if any element is null
114   */
115  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) {
116    return construct(e1, e2, e3, e4, e5);
117  }
118
119  /**
120   * Returns an immutable list containing the given elements, in order.
121   *
122   * @throws NullPointerException if any element is null
123   */
124  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
125    return construct(e1, e2, e3, e4, e5, e6);
126  }
127
128  /**
129   * Returns an immutable list containing the given elements, in order.
130   *
131   * @throws NullPointerException if any element is null
132   */
133  public static <E> ImmutableList<E> of(
134      E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
135    return construct(e1, e2, e3, e4, e5, e6, e7);
136  }
137
138  /**
139   * Returns an immutable list containing the given elements, in order.
140   *
141   * @throws NullPointerException if any element is null
142   */
143  public static <E> ImmutableList<E> of(
144      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
145    return construct(e1, e2, e3, e4, e5, e6, e7, e8);
146  }
147
148  /**
149   * Returns an immutable list containing the given elements, in order.
150   *
151   * @throws NullPointerException if any element is null
152   */
153  public static <E> ImmutableList<E> of(
154      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
155    return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9);
156  }
157
158  /**
159   * Returns an immutable list containing the given elements, in order.
160   *
161   * @throws NullPointerException if any element is null
162   */
163  public static <E> ImmutableList<E> of(
164      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
165    return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
166  }
167
168  /**
169   * Returns an immutable list containing the given elements, in order.
170   *
171   * @throws NullPointerException if any element is null
172   */
173  public static <E> ImmutableList<E> of(
174      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {
175    return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11);
176  }
177
178  // These go up to eleven. After that, you just get the varargs form, and
179  // whatever warnings might come along with it. :(
180
181  /**
182   * Returns an immutable list containing the given elements, in order.
183   *
184   * @throws NullPointerException if any element is null
185   * @since 3.0 (source-compatible since 2.0)
186   */
187  public static <E> ImmutableList<E> of(
188      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12,
189      E... others) {
190    Object[] array = new Object[12 + others.length];
191    array[0] = e1;
192    array[1] = e2;
193    array[2] = e3;
194    array[3] = e4;
195    array[4] = e5;
196    array[5] = e6;
197    array[6] = e7;
198    array[7] = e8;
199    array[8] = e9;
200    array[9] = e10;
201    array[10] = e11;
202    array[11] = e12;
203    System.arraycopy(others, 0, array, 12, others.length);
204    return construct(array);
205  }
206
207  /**
208   * Returns an immutable list containing the given elements, in order. If
209   * {@code elements} is a {@link Collection}, this method behaves exactly as
210   * {@link #copyOf(Collection)}; otherwise, it behaves exactly as {@code
211   * copyOf(elements.iterator()}.
212   *
213   * @throws NullPointerException if any of {@code elements} is null
214   */
215  public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {
216    checkNotNull(elements); // TODO(kevinb): is this here only for GWT?
217    return (elements instanceof Collection)
218      ? copyOf(Collections2.cast(elements))
219      : copyOf(elements.iterator());
220  }
221
222  /**
223   * Returns an immutable list containing the given elements, in order.
224   *
225   * <p>Despite the method name, this method attempts to avoid actually copying
226   * the data when it is safe to do so. The exact circumstances under which a
227   * copy will or will not be performed are undocumented and subject to change.
228   *
229   * <p>Note that if {@code list} is a {@code List<String>}, then {@code
230   * ImmutableList.copyOf(list)} returns an {@code ImmutableList<String>}
231   * containing each of the strings in {@code list}, while
232   * ImmutableList.of(list)} returns an {@code ImmutableList<List<String>>}
233   * containing one element (the given list itself).
234   *
235   * <p>This method is safe to use even when {@code elements} is a synchronized
236   * or concurrent collection that is currently being modified by another
237   * thread.
238   *
239   * @throws NullPointerException if any of {@code elements} is null
240   */
241  public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
242    if (elements instanceof ImmutableCollection) {
243      @SuppressWarnings("unchecked") // all supported methods are covariant
244      ImmutableList<E> list = ((ImmutableCollection<E>) elements).asList();
245      return list.isPartialView() ? copyFromCollection(list) : list;
246    }
247    return copyFromCollection(elements);
248  }
249
250  /**
251   * Returns an immutable list containing the given elements, in order.
252   *
253   * @throws NullPointerException if any of {@code elements} is null
254   */
255  public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
256    return copyFromCollection(Lists.newArrayList(elements));
257  }
258
259  /**
260   * Returns an immutable list containing the given elements, in order.
261   *
262   * @throws NullPointerException if any of {@code elements} is null
263   * @since 3.0
264   */
265  public static <E> ImmutableList<E> copyOf(E[] elements) {
266    switch (elements.length) {
267      case 0:
268        return ImmutableList.of();
269      case 1:
270        return new SingletonImmutableList<E>(elements[0]);
271      default:
272        return construct(elements.clone());
273    }
274  }
275
276  private static <E> ImmutableList<E> copyFromCollection(
277      Collection<? extends E> collection) {
278    Object[] elements = collection.toArray();
279    switch (elements.length) {
280      case 0:
281        return of();
282      case 1:
283        @SuppressWarnings("unchecked") // collection had only Es in it
284        ImmutableList<E> list = new SingletonImmutableList<E>((E) elements[0]);
285        return list;
286      default:
287        // safe to use the array without copying it
288        // as specified by Collection.toArray().
289        return construct(elements);
290    }
291  }
292
293  /** {@code elements} has to be internally created array. */
294  private static <E> ImmutableList<E> construct(Object... elements) {
295    for (int i = 0; i < elements.length; i++) {
296      checkElementNotNull(elements[i], i);
297    }
298    return new RegularImmutableList<E>(elements);
299  }
300
301  // We do this instead of Preconditions.checkNotNull to save boxing and array
302  // creation cost.
303  private static Object checkElementNotNull(Object element, int index) {
304    if (element == null) {
305      throw new NullPointerException("at index " + index);
306    }
307    return element;
308  }
309
310  ImmutableList() {}
311
312  // This declaration is needed to make List.iterator() and
313  // ImmutableCollection.iterator() consistent.
314  @Override public UnmodifiableIterator<E> iterator() {
315    return listIterator();
316  }
317
318  @Override public UnmodifiableListIterator<E> listIterator() {
319    return listIterator(0);
320  }
321
322  @Override public abstract UnmodifiableListIterator<E> listIterator(int index);
323
324  // Mark these two methods with @Nullable
325
326  @Override
327  public abstract int indexOf(@Nullable Object object);
328
329  @Override
330  public abstract int lastIndexOf(@Nullable Object object);
331
332  // constrain the return type to ImmutableList<E>
333
334  /**
335   * Returns an immutable list of the elements between the specified {@code
336   * fromIndex}, inclusive, and {@code toIndex}, exclusive. (If {@code
337   * fromIndex} and {@code toIndex} are equal, the empty immutable list is
338   * returned.)
339   */
340  @Override
341  public abstract ImmutableList<E> subList(int fromIndex, int toIndex);
342
343  /**
344   * Guaranteed to throw an exception and leave the list unmodified.
345   *
346   * @throws UnsupportedOperationException always
347   */
348  @Override
349  public final boolean addAll(int index, Collection<? extends E> newElements) {
350    throw new UnsupportedOperationException();
351  }
352
353  /**
354   * Guaranteed to throw an exception and leave the list unmodified.
355   *
356   * @throws UnsupportedOperationException always
357   */
358  @Override
359  public final E set(int index, E element) {
360    throw new UnsupportedOperationException();
361  }
362
363  /**
364   * Guaranteed to throw an exception and leave the list unmodified.
365   *
366   * @throws UnsupportedOperationException always
367   */
368  @Override
369  public final void add(int index, E element) {
370    throw new UnsupportedOperationException();
371  }
372
373  /**
374   * Guaranteed to throw an exception and leave the list unmodified.
375   *
376   * @throws UnsupportedOperationException always
377   */
378  @Override
379  public final E remove(int index) {
380    throw new UnsupportedOperationException();
381  }
382
383  /**
384   * Returns this list instance.
385   *
386   * @since 2.0
387   */
388  @Override public ImmutableList<E> asList() {
389    return this;
390  }
391
392  /**
393   * Returns a view of this immutable list in reverse order. For example, {@code
394   * ImmutableList.of(1, 2, 3).reverse()} is equivalent to {@code
395   * ImmutableList.of(3, 2, 1)}.
396   *
397   * @return a view of this immutable list in reverse order
398   * @since 7.0
399   */
400  public ImmutableList<E> reverse() {
401    return new ReverseImmutableList<E>(this);
402  }
403
404  private static class ReverseImmutableList<E> extends ImmutableList<E> {
405    private transient final ImmutableList<E> forwardList;
406    private transient final int size;
407
408    ReverseImmutableList(ImmutableList<E> backingList) {
409      this.forwardList = backingList;
410      this.size = backingList.size();
411    }
412
413    private int reverseIndex(int index) {
414      return (size - 1) - index;
415    }
416
417    private int reversePosition(int index) {
418      return size - index;
419    }
420
421    @Override public ImmutableList<E> reverse() {
422      return forwardList;
423    }
424
425    @Override public boolean contains(@Nullable Object object) {
426      return forwardList.contains(object);
427    }
428
429    @Override public boolean containsAll(Collection<?> targets) {
430      return forwardList.containsAll(targets);
431    }
432
433    @Override public int indexOf(@Nullable Object object) {
434      int index = forwardList.lastIndexOf(object);
435      return (index >= 0) ? reverseIndex(index) : -1;
436    }
437
438    @Override public int lastIndexOf(@Nullable Object object) {
439      int index = forwardList.indexOf(object);
440      return (index >= 0) ? reverseIndex(index) : -1;
441    }
442
443    @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
444      Preconditions.checkPositionIndexes(fromIndex, toIndex, size);
445      return forwardList.subList(
446          reversePosition(toIndex), reversePosition(fromIndex)).reverse();
447    }
448
449    @Override public E get(int index) {
450      Preconditions.checkElementIndex(index, size);
451      return forwardList.get(reverseIndex(index));
452    }
453
454    @Override public UnmodifiableListIterator<E> listIterator(int index) {
455      Preconditions.checkPositionIndex(index, size);
456      final UnmodifiableListIterator<E> forward =
457          forwardList.listIterator(reversePosition(index));
458      return new UnmodifiableListIterator<E>() {
459        @Override public boolean hasNext() {
460          return forward.hasPrevious();
461        }
462
463        @Override public boolean hasPrevious() {
464          return forward.hasNext();
465        }
466
467        @Override public E next() {
468          return forward.previous();
469        }
470
471        @Override public int nextIndex() {
472          return reverseIndex(forward.previousIndex());
473        }
474
475        @Override public E previous() {
476          return forward.next();
477        }
478
479        @Override public int previousIndex() {
480          return reverseIndex(forward.nextIndex());
481        }
482      };
483    }
484
485    @Override public int size() {
486      return size;
487    }
488
489    @Override public boolean isEmpty() {
490      return forwardList.isEmpty();
491    }
492
493    @Override boolean isPartialView() {
494      return forwardList.isPartialView();
495    }
496  }
497
498  @Override public boolean equals(Object obj) {
499    return Lists.equalsImpl(this, obj);
500  }
501
502  @Override public int hashCode() {
503    return Lists.hashCodeImpl(this);
504  }
505
506  /*
507   * Serializes ImmutableLists as their logical contents. This ensures that
508   * implementation types do not leak into the serialized representation.
509   */
510  private static class SerializedForm implements Serializable {
511    final Object[] elements;
512    SerializedForm(Object[] elements) {
513      this.elements = elements;
514    }
515    Object readResolve() {
516      return copyOf(elements);
517    }
518    private static final long serialVersionUID = 0;
519  }
520
521  private void readObject(ObjectInputStream stream)
522      throws InvalidObjectException {
523    throw new InvalidObjectException("Use SerializedForm");
524  }
525
526  @Override Object writeReplace() {
527    return new SerializedForm(toArray());
528  }
529
530  /**
531   * Returns a new builder. The generated builder is equivalent to the builder
532   * created by the {@link Builder} constructor.
533   */
534  public static <E> Builder<E> builder() {
535    return new Builder<E>();
536  }
537
538  /**
539   * A builder for creating immutable list instances, especially {@code public
540   * static final} lists ("constant lists"). Example: <pre>   {@code
541   *
542   *   public static final ImmutableList<Color> GOOGLE_COLORS
543   *       = new ImmutableList.Builder<Color>()
544   *           .addAll(WEBSAFE_COLORS)
545   *           .add(new Color(0, 191, 255))
546   *           .build();}</pre>
547   *
548   * Builder instances can be reused; it is safe to call {@link #build} multiple
549   * times to build multiple lists in series. Each new list contains all the
550   * elements of the ones created before it.
551   *
552   * @since 2.0 (imported from Google Collections Library)
553   */
554  public static final class Builder<E> extends ImmutableCollection.Builder<E> {
555    private final ArrayList<E> contents = Lists.newArrayList();
556
557    /**
558     * Creates a new builder. The returned builder is equivalent to the builder
559     * generated by {@link ImmutableList#builder}.
560     */
561    public Builder() {}
562
563    /**
564     * Adds {@code element} to the {@code ImmutableList}.
565     *
566     * @param element the element to add
567     * @return this {@code Builder} object
568     * @throws NullPointerException if {@code element} is null
569     */
570    @Override public Builder<E> add(E element) {
571      contents.add(checkNotNull(element));
572      return this;
573    }
574
575    /**
576     * Adds each element of {@code elements} to the {@code ImmutableList}.
577     *
578     * @param elements the {@code Iterable} to add to the {@code ImmutableList}
579     * @return this {@code Builder} object
580     * @throws NullPointerException if {@code elements} is null or contains a
581     *     null element
582     */
583    @Override public Builder<E> addAll(Iterable<? extends E> elements) {
584      if (elements instanceof Collection) {
585        Collection<?> collection = (Collection<?>) elements;
586        contents.ensureCapacity(contents.size() + collection.size());
587      }
588      super.addAll(elements);
589      return this;
590    }
591
592    /**
593     * Adds each element of {@code elements} to the {@code ImmutableList}.
594     *
595     * @param elements the {@code Iterable} to add to the {@code ImmutableList}
596     * @return this {@code Builder} object
597     * @throws NullPointerException if {@code elements} is null or contains a
598     *     null element
599     */
600    @Override public Builder<E> add(E... elements) {
601      contents.ensureCapacity(contents.size() + elements.length);
602      super.add(elements);
603      return this;
604    }
605
606    /**
607     * Adds each element of {@code elements} to the {@code ImmutableList}.
608     *
609     * @param elements the {@code Iterable} to add to the {@code ImmutableList}
610     * @return this {@code Builder} object
611     * @throws NullPointerException if {@code elements} is null or contains a
612     *     null element
613     */
614    @Override public Builder<E> addAll(Iterator<? extends E> elements) {
615      super.addAll(elements);
616      return this;
617    }
618
619    /**
620     * Returns a newly-created {@code ImmutableList} based on the contents of
621     * the {@code Builder}.
622     */
623    @Override public ImmutableList<E> build() {
624      return copyOf(contents);
625    }
626  }
627}
628