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.checkElementIndex;
021import static com.google.common.base.Preconditions.checkNotNull;
022import static com.google.common.base.Preconditions.checkPositionIndex;
023import static com.google.common.base.Preconditions.checkPositionIndexes;
024import static com.google.common.collect.CollectPreconditions.checkNonnegative;
025import static com.google.common.collect.ObjectArrays.checkElementsNotNull;
026import static com.google.common.collect.RegularImmutableList.EMPTY;
027
028import com.google.common.annotations.GwtCompatible;
029import com.google.common.annotations.GwtIncompatible;
030import com.google.common.annotations.J2ktIncompatible;
031import com.google.errorprone.annotations.CanIgnoreReturnValue;
032import com.google.errorprone.annotations.DoNotCall;
033import com.google.errorprone.annotations.InlineMe;
034import java.io.InvalidObjectException;
035import java.io.ObjectInputStream;
036import java.io.Serializable;
037import java.util.Arrays;
038import java.util.Collection;
039import java.util.Collections;
040import java.util.Comparator;
041import java.util.Iterator;
042import java.util.List;
043import java.util.RandomAccess;
044import java.util.stream.Collector;
045import javax.annotation.CheckForNull;
046import org.checkerframework.checker.nullness.qual.Nullable;
047
048/**
049 * A {@link List} whose contents will never change, with many other important properties detailed at
050 * {@link ImmutableCollection}.
051 *
052 * <p>See the Guava User Guide article on <a href=
053 * "https://github.com/google/guava/wiki/ImmutableCollectionsExplained">immutable collections</a>.
054 *
055 * @see ImmutableMap
056 * @see ImmutableSet
057 * @author Kevin Bourrillion
058 * @since 2.0
059 */
060@GwtCompatible(serializable = true, emulated = true)
061@SuppressWarnings("serial") // we're overriding default serialization
062@ElementTypesAreNonnullByDefault
063public abstract class ImmutableList<E> extends ImmutableCollection<E>
064    implements List<E>, RandomAccess {
065
066  /**
067   * Returns a {@code Collector} that accumulates the input elements into a new {@code
068   * ImmutableList}, in encounter order.
069   */
070  @SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
071  @IgnoreJRERequirement // Users will use this only if they're already using streams.
072  static <E> Collector<E, ?, ImmutableList<E>> toImmutableList() {
073    return CollectCollectors.toImmutableList();
074  }
075
076  /**
077   * Returns the empty immutable list. This list behaves and performs comparably to {@link
078   * Collections#emptyList}, and is preferable mainly for consistency and maintainability of your
079   * code.
080   *
081   * <p><b>Performance note:</b> the instance returned is a singleton.
082   */
083  // Casting to any type is safe because the list will never hold any elements.
084  @SuppressWarnings("unchecked")
085  public static <E> ImmutableList<E> of() {
086    return (ImmutableList<E>) EMPTY;
087  }
088
089  /**
090   * Returns an immutable list containing a single element. This list behaves and performs
091   * comparably to {@link Collections#singletonList}, but will not accept a null element. It is
092   * preferable mainly for consistency and maintainability of your code.
093   *
094   * @throws NullPointerException if {@code element} is null
095   */
096  public static <E> ImmutableList<E> of(E element) {
097    return construct(element);
098  }
099
100  /**
101   * Returns an immutable list containing the given elements, in order.
102   *
103   * @throws NullPointerException if any element is null
104   */
105  public static <E> ImmutableList<E> of(E e1, E e2) {
106    return construct(e1, e2);
107  }
108
109  /**
110   * Returns an immutable list containing the given elements, in order.
111   *
112   * @throws NullPointerException if any element is null
113   */
114  public static <E> ImmutableList<E> of(E e1, E e2, E e3) {
115    return construct(e1, e2, e3);
116  }
117
118  /**
119   * Returns an immutable list containing the given elements, in order.
120   *
121   * @throws NullPointerException if any element is null
122   */
123  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) {
124    return construct(e1, e2, e3, e4);
125  }
126
127  /**
128   * Returns an immutable list containing the given elements, in order.
129   *
130   * @throws NullPointerException if any element is null
131   */
132  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) {
133    return construct(e1, e2, e3, e4, e5);
134  }
135
136  /**
137   * Returns an immutable list containing the given elements, in order.
138   *
139   * @throws NullPointerException if any element is null
140   */
141  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
142    return construct(e1, e2, e3, e4, e5, e6);
143  }
144
145  /**
146   * Returns an immutable list containing the given elements, in order.
147   *
148   * @throws NullPointerException if any element is null
149   */
150  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
151    return construct(e1, e2, e3, e4, e5, e6, e7);
152  }
153
154  /**
155   * Returns an immutable list containing the given elements, in order.
156   *
157   * @throws NullPointerException if any element is null
158   */
159  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
160    return construct(e1, e2, e3, e4, e5, e6, e7, e8);
161  }
162
163  /**
164   * Returns an immutable list containing the given elements, in order.
165   *
166   * @throws NullPointerException if any element is null
167   */
168  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
169    return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9);
170  }
171
172  /**
173   * Returns an immutable list containing the given elements, in order.
174   *
175   * @throws NullPointerException if any element is null
176   */
177  public static <E> ImmutableList<E> of(
178      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
179    return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
180  }
181
182  /**
183   * Returns an immutable list containing the given elements, in order.
184   *
185   * @throws NullPointerException if any element is null
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) {
189    return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11);
190  }
191
192  // These go up to eleven. After that, you just get the varargs form, and
193  // whatever warnings might come along with it. :(
194
195  /**
196   * Returns an immutable list containing the given elements, in order.
197   *
198   * <p>The array {@code others} must not be longer than {@code Integer.MAX_VALUE - 12}.
199   *
200   * @throws NullPointerException if any element is null
201   * @since 3.0 (source-compatible since 2.0)
202   */
203  @SafeVarargs // For Eclipse. For internal javac we have disabled this pointless type of warning.
204  public static <E> ImmutableList<E> of(
205      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12, E... others) {
206    checkArgument(
207        others.length <= Integer.MAX_VALUE - 12, "the total number of elements must fit in an int");
208    Object[] array = new Object[12 + others.length];
209    array[0] = e1;
210    array[1] = e2;
211    array[2] = e3;
212    array[3] = e4;
213    array[4] = e5;
214    array[5] = e6;
215    array[6] = e7;
216    array[7] = e8;
217    array[8] = e9;
218    array[9] = e10;
219    array[10] = e11;
220    array[11] = e12;
221    System.arraycopy(others, 0, array, 12, others.length);
222    return construct(array);
223  }
224
225  /**
226   * Returns an immutable list containing the given elements, in order. If {@code elements} is a
227   * {@link Collection}, this method behaves exactly as {@link #copyOf(Collection)}; otherwise, it
228   * behaves exactly as {@code copyOf(elements.iterator()}.
229   *
230   * @throws NullPointerException if {@code elements} contains a null element
231   */
232  public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {
233    checkNotNull(elements); // TODO(kevinb): is this here only for GWT?
234    return (elements instanceof Collection)
235        ? copyOf((Collection<? extends E>) elements)
236        : copyOf(elements.iterator());
237  }
238
239  /**
240   * Returns an immutable list containing the given elements, in order.
241   *
242   * <p>Despite the method name, this method attempts to avoid actually copying the data when it is
243   * safe to do so. The exact circumstances under which a copy will or will not be performed are
244   * undocumented and subject to change.
245   *
246   * <p>Note that if {@code list} is a {@code List<String>}, then {@code ImmutableList.copyOf(list)}
247   * returns an {@code ImmutableList<String>} containing each of the strings in {@code list}, while
248   * {@code ImmutableList.of(list)} returns an {@code ImmutableList<List<String>>} containing one
249   * element (the given list itself).
250   *
251   * <p>This method is safe to use even when {@code elements} is a synchronized or concurrent
252   * collection that is currently being modified by another thread.
253   *
254   * @throws NullPointerException if {@code elements} contains a null element
255   */
256  public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
257    if (elements instanceof ImmutableCollection) {
258      @SuppressWarnings("unchecked") // all supported methods are covariant
259      ImmutableList<E> list = ((ImmutableCollection<E>) elements).asList();
260      return list.isPartialView() ? ImmutableList.<E>asImmutableList(list.toArray()) : list;
261    }
262    return construct(elements.toArray());
263  }
264
265  /**
266   * Returns an immutable list containing the given elements, in order.
267   *
268   * @throws NullPointerException if {@code elements} contains a null element
269   */
270  public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
271    // We special-case for 0 or 1 elements, but going further is madness.
272    if (!elements.hasNext()) {
273      return of();
274    }
275    E first = elements.next();
276    if (!elements.hasNext()) {
277      return of(first);
278    } else {
279      return new ImmutableList.Builder<E>().add(first).addAll(elements).build();
280    }
281  }
282
283  /**
284   * Returns an immutable list containing the given elements, in order.
285   *
286   * @throws NullPointerException if {@code elements} contains a null element
287   * @since 3.0
288   */
289  public static <E> ImmutableList<E> copyOf(E[] elements) {
290    return (elements.length == 0)
291        ? ImmutableList.<E>of()
292        : ImmutableList.<E>construct(elements.clone());
293  }
294
295  /**
296   * Returns an immutable list containing the given elements, sorted according to their natural
297   * order. The sorting algorithm used is stable, so elements that compare as equal will stay in the
298   * order in which they appear in the input.
299   *
300   * <p>If your data has no duplicates, or you wish to deduplicate elements, use {@code
301   * ImmutableSortedSet.copyOf(elements)}; if you want a {@code List} you can use its {@code
302   * asList()} view.
303   *
304   * <p><b>Java 8+ users:</b> If you want to convert a {@link java.util.stream.Stream} to a sorted
305   * {@code ImmutableList}, use {@code stream.sorted().collect(toImmutableList())}.
306   *
307   * @throws NullPointerException if any element in the input is null
308   * @since 21.0
309   */
310  public static <E extends Comparable<? super E>> ImmutableList<E> sortedCopyOf(
311      Iterable<? extends E> elements) {
312    Comparable<?>[] array = Iterables.toArray(elements, new Comparable<?>[0]);
313    checkElementsNotNull((Object[]) array);
314    Arrays.sort(array);
315    return asImmutableList(array);
316  }
317
318  /**
319   * Returns an immutable list containing the given elements, in sorted order relative to the
320   * specified comparator. The sorting algorithm used is stable, so elements that compare as equal
321   * will stay in the order in which they appear in the input.
322   *
323   * <p>If your data has no duplicates, or you wish to deduplicate elements, use {@code
324   * ImmutableSortedSet.copyOf(comparator, elements)}; if you want a {@code List} you can use its
325   * {@code asList()} view.
326   *
327   * <p><b>Java 8+ users:</b> If you want to convert a {@link java.util.stream.Stream} to a sorted
328   * {@code ImmutableList}, use {@code stream.sorted(comparator).collect(toImmutableList())}.
329   *
330   * @throws NullPointerException if any element in the input is null
331   * @since 21.0
332   */
333  public static <E> ImmutableList<E> sortedCopyOf(
334      Comparator<? super E> comparator, Iterable<? extends E> elements) {
335    checkNotNull(comparator);
336    @SuppressWarnings("unchecked") // all supported methods are covariant
337    E[] array = (E[]) Iterables.toArray(elements);
338    checkElementsNotNull(array);
339    Arrays.sort(array, comparator);
340    return asImmutableList(array);
341  }
342
343  /** Views the array as an immutable list. Checks for nulls; does not copy. */
344  private static <E> ImmutableList<E> construct(Object... elements) {
345    return asImmutableList(checkElementsNotNull(elements));
346  }
347
348  /**
349   * Views the array as an immutable list. Does not check for nulls; does not copy.
350   *
351   * <p>The array must be internally created.
352   */
353  static <E> ImmutableList<E> asImmutableList(Object[] elements) {
354    return asImmutableList(elements, elements.length);
355  }
356
357  /** Views the array as an immutable list. Does not check for nulls. */
358  static <E> ImmutableList<E> asImmutableList(@Nullable Object[] elements, int length) {
359    if (length == 0) {
360      return of();
361    }
362    return new RegularImmutableList<E>(elements, length);
363  }
364
365  ImmutableList() {}
366
367  // This declaration is needed to make List.iterator() and
368  // ImmutableCollection.iterator() consistent.
369  @Override
370  public UnmodifiableIterator<E> iterator() {
371    return listIterator();
372  }
373
374  @Override
375  public UnmodifiableListIterator<E> listIterator() {
376    return listIterator(0);
377  }
378
379  @SuppressWarnings("unchecked")
380  @Override
381  public UnmodifiableListIterator<E> listIterator(int index) {
382    checkPositionIndex(index, size());
383    if (isEmpty()) {
384      return (UnmodifiableListIterator<E>) EMPTY_ITR;
385    } else {
386      return new Itr<E>(this, index);
387    }
388  }
389
390  /** A singleton implementation of iterator() for the empty ImmutableList. */
391  private static final UnmodifiableListIterator<Object> EMPTY_ITR =
392      new Itr<Object>(RegularImmutableList.EMPTY, 0);
393
394  static class Itr<E> extends AbstractIndexedListIterator<E> {
395    private final ImmutableList<E> list;
396
397    Itr(ImmutableList<E> list, int index) {
398      super(list.size(), index);
399      this.list = list;
400    }
401
402    @Override
403    protected E get(int index) {
404      return list.get(index);
405    }
406  }
407
408  @Override
409  public int indexOf(@CheckForNull Object object) {
410    return (object == null) ? -1 : Lists.indexOfImpl(this, object);
411  }
412
413  @Override
414  public int lastIndexOf(@CheckForNull Object object) {
415    return (object == null) ? -1 : Lists.lastIndexOfImpl(this, object);
416  }
417
418  @Override
419  public boolean contains(@CheckForNull Object object) {
420    return indexOf(object) >= 0;
421  }
422
423  // constrain the return type to ImmutableList<E>
424
425  /**
426   * Returns an immutable list of the elements between the specified {@code fromIndex}, inclusive,
427   * and {@code toIndex}, exclusive. (If {@code fromIndex} and {@code toIndex} are equal, the empty
428   * immutable list is returned.)
429   *
430   * <p><b>Note:</b> in almost all circumstances, the returned {@link ImmutableList} retains a
431   * strong reference to {@code this}, which may prevent the original list from being garbage
432   * collected. If you want the original list to be eligible for garbage collection, you should
433   * create and use a copy of the sub list (e.g., {@code
434   * ImmutableList.copyOf(originalList.subList(...))}).
435   */
436  @Override
437  public ImmutableList<E> subList(int fromIndex, int toIndex) {
438    checkPositionIndexes(fromIndex, toIndex, size());
439    int length = toIndex - fromIndex;
440    if (length == size()) {
441      return this;
442    } else if (length == 0) {
443      return of();
444    } else {
445      return subListUnchecked(fromIndex, toIndex);
446    }
447  }
448
449  /**
450   * Called by the default implementation of {@link #subList} when {@code toIndex - fromIndex > 1},
451   * after index validation has already been performed.
452   */
453  ImmutableList<E> subListUnchecked(int fromIndex, int toIndex) {
454    return new SubList(fromIndex, toIndex - fromIndex);
455  }
456
457  class SubList extends ImmutableList<E> {
458    final transient int offset;
459    final transient int length;
460
461    SubList(int offset, int length) {
462      this.offset = offset;
463      this.length = length;
464    }
465
466    @Override
467    public int size() {
468      return length;
469    }
470
471    @Override
472    @CheckForNull
473    @Nullable
474    Object[] internalArray() {
475      return ImmutableList.this.internalArray();
476    }
477
478    @Override
479    int internalArrayStart() {
480      return ImmutableList.this.internalArrayStart() + offset;
481    }
482
483    @Override
484    int internalArrayEnd() {
485      return ImmutableList.this.internalArrayStart() + offset + length;
486    }
487
488    @Override
489    public E get(int index) {
490      checkElementIndex(index, length);
491      return ImmutableList.this.get(index + offset);
492    }
493
494    @Override
495    public ImmutableList<E> subList(int fromIndex, int toIndex) {
496      checkPositionIndexes(fromIndex, toIndex, length);
497      return ImmutableList.this.subList(fromIndex + offset, toIndex + offset);
498    }
499
500    @Override
501    boolean isPartialView() {
502      return true;
503    }
504
505    // redeclare to help optimizers with b/310253115
506    @SuppressWarnings("RedundantOverride")
507    @Override
508    @J2ktIncompatible // serialization
509    @GwtIncompatible // serialization
510    Object writeReplace() {
511      return super.writeReplace();
512    }
513  }
514
515  /**
516   * Guaranteed to throw an exception and leave the list unmodified.
517   *
518   * @throws UnsupportedOperationException always
519   * @deprecated Unsupported operation.
520   */
521  @CanIgnoreReturnValue
522  @Deprecated
523  @Override
524  @DoNotCall("Always throws UnsupportedOperationException")
525  public final boolean addAll(int index, Collection<? extends E> newElements) {
526    throw new UnsupportedOperationException();
527  }
528
529  /**
530   * Guaranteed to throw an exception and leave the list unmodified.
531   *
532   * @throws UnsupportedOperationException always
533   * @deprecated Unsupported operation.
534   */
535  @CanIgnoreReturnValue
536  @Deprecated
537  @Override
538  @DoNotCall("Always throws UnsupportedOperationException")
539  public final E set(int index, E element) {
540    throw new UnsupportedOperationException();
541  }
542
543  /**
544   * Guaranteed to throw an exception and leave the list unmodified.
545   *
546   * @throws UnsupportedOperationException always
547   * @deprecated Unsupported operation.
548   */
549  @Deprecated
550  @Override
551  @DoNotCall("Always throws UnsupportedOperationException")
552  public final void add(int index, E element) {
553    throw new UnsupportedOperationException();
554  }
555
556  /**
557   * Guaranteed to throw an exception and leave the list unmodified.
558   *
559   * @throws UnsupportedOperationException always
560   * @deprecated Unsupported operation.
561   */
562  @CanIgnoreReturnValue
563  @Deprecated
564  @Override
565  @DoNotCall("Always throws UnsupportedOperationException")
566  public final E remove(int index) {
567    throw new UnsupportedOperationException();
568  }
569
570  /**
571   * Returns this list instance.
572   *
573   * @since 2.0
574   * @deprecated There is no reason to use this; it always returns {@code this}.
575   */
576  @InlineMe(replacement = "this")
577  @Deprecated
578  @Override
579  public final ImmutableList<E> asList() {
580    return this;
581  }
582
583  @Override
584  int copyIntoArray(@Nullable Object[] dst, int offset) {
585    // this loop is faster for RandomAccess instances, which ImmutableLists are
586    int size = size();
587    for (int i = 0; i < size; i++) {
588      dst[offset + i] = get(i);
589    }
590    return offset + size;
591  }
592
593  /**
594   * Returns a view of this immutable list in reverse order. For example, {@code ImmutableList.of(1,
595   * 2, 3).reverse()} is equivalent to {@code ImmutableList.of(3, 2, 1)}.
596   *
597   * @return a view of this immutable list in reverse order
598   * @since 7.0
599   */
600  public ImmutableList<E> reverse() {
601    return (size() <= 1) ? this : new ReverseImmutableList<E>(this);
602  }
603
604  private static class ReverseImmutableList<E> extends ImmutableList<E> {
605    private final transient ImmutableList<E> forwardList;
606
607    ReverseImmutableList(ImmutableList<E> backingList) {
608      this.forwardList = backingList;
609    }
610
611    private int reverseIndex(int index) {
612      return (size() - 1) - index;
613    }
614
615    private int reversePosition(int index) {
616      return size() - index;
617    }
618
619    @Override
620    public ImmutableList<E> reverse() {
621      return forwardList;
622    }
623
624    @Override
625    public boolean contains(@CheckForNull Object object) {
626      return forwardList.contains(object);
627    }
628
629    @Override
630    public int indexOf(@CheckForNull Object object) {
631      int index = forwardList.lastIndexOf(object);
632      return (index >= 0) ? reverseIndex(index) : -1;
633    }
634
635    @Override
636    public int lastIndexOf(@CheckForNull Object object) {
637      int index = forwardList.indexOf(object);
638      return (index >= 0) ? reverseIndex(index) : -1;
639    }
640
641    @Override
642    public ImmutableList<E> subList(int fromIndex, int toIndex) {
643      checkPositionIndexes(fromIndex, toIndex, size());
644      return forwardList.subList(reversePosition(toIndex), reversePosition(fromIndex)).reverse();
645    }
646
647    @Override
648    public E get(int index) {
649      checkElementIndex(index, size());
650      return forwardList.get(reverseIndex(index));
651    }
652
653    @Override
654    public int size() {
655      return forwardList.size();
656    }
657
658    @Override
659    boolean isPartialView() {
660      return forwardList.isPartialView();
661    }
662
663    // redeclare to help optimizers with b/310253115
664    @SuppressWarnings("RedundantOverride")
665    @Override
666    @J2ktIncompatible // serialization
667    @GwtIncompatible // serialization
668    Object writeReplace() {
669      return super.writeReplace();
670    }
671  }
672
673  @Override
674  public boolean equals(@CheckForNull Object obj) {
675    return Lists.equalsImpl(this, obj);
676  }
677
678  @Override
679  public int hashCode() {
680    int hashCode = 1;
681    int n = size();
682    for (int i = 0; i < n; i++) {
683      hashCode = 31 * hashCode + get(i).hashCode();
684
685      hashCode = ~~hashCode;
686      // needed to deal with GWT integer overflow
687    }
688    return hashCode;
689  }
690
691  /*
692   * Serializes ImmutableLists as their logical contents. This ensures that
693   * implementation types do not leak into the serialized representation.
694   */
695  @J2ktIncompatible // serialization
696  static class SerializedForm implements Serializable {
697    final Object[] elements;
698
699    SerializedForm(Object[] elements) {
700      this.elements = elements;
701    }
702
703    Object readResolve() {
704      return copyOf(elements);
705    }
706
707    private static final long serialVersionUID = 0;
708  }
709
710  @J2ktIncompatible // serialization
711  private void readObject(ObjectInputStream stream) throws InvalidObjectException {
712    throw new InvalidObjectException("Use SerializedForm");
713  }
714
715  @Override
716  @J2ktIncompatible // serialization
717  @GwtIncompatible // serialization
718  Object writeReplace() {
719    return new SerializedForm(toArray());
720  }
721
722  /**
723   * Returns a new builder. The generated builder is equivalent to the builder created by the {@link
724   * Builder} constructor.
725   */
726  public static <E> Builder<E> builder() {
727    return new Builder<>();
728  }
729
730  /**
731   * Returns a new builder, expecting the specified number of elements to be added.
732   *
733   * <p>If {@code expectedSize} is exactly the number of elements added to the builder before {@link
734   * Builder#build} is called, the builder is likely to perform better than an unsized {@link
735   * #builder()} would have.
736   *
737   * <p>It is not specified if any performance benefits apply if {@code expectedSize} is close to,
738   * but not exactly, the number of elements added to the builder.
739   *
740   * @since 23.1
741   */
742  public static <E> Builder<E> builderWithExpectedSize(int expectedSize) {
743    checkNonnegative(expectedSize, "expectedSize");
744    return new ImmutableList.Builder<>(expectedSize);
745  }
746
747  /**
748   * A builder for creating immutable list instances, especially {@code public static final} lists
749   * ("constant lists"). Example:
750   *
751   * <pre>{@code
752   * public static final ImmutableList<Color> GOOGLE_COLORS
753   *     = new ImmutableList.Builder<Color>()
754   *         .addAll(WEBSAFE_COLORS)
755   *         .add(new Color(0, 191, 255))
756   *         .build();
757   * }</pre>
758   *
759   * <p>Elements appear in the resulting list in the same order they were added to the builder.
760   *
761   * <p>Builder instances can be reused; it is safe to call {@link #build} multiple times to build
762   * multiple lists in series. Each new list contains all the elements of the ones created before
763   * it.
764   *
765   * @since 2.0
766   */
767  public static final class Builder<E> extends ImmutableCollection.ArrayBasedBuilder<E> {
768    /**
769     * Creates a new builder. The returned builder is equivalent to the builder generated by {@link
770     * ImmutableList#builder}.
771     */
772    public Builder() {
773      this(DEFAULT_INITIAL_CAPACITY);
774    }
775
776    Builder(int capacity) {
777      super(capacity);
778    }
779
780    /**
781     * Adds {@code element} to the {@code ImmutableList}.
782     *
783     * @param element the element to add
784     * @return this {@code Builder} object
785     * @throws NullPointerException if {@code element} is null
786     */
787    @CanIgnoreReturnValue
788    @Override
789    public Builder<E> add(E element) {
790      super.add(element);
791      return this;
792    }
793
794    /**
795     * Adds each element of {@code elements} to the {@code ImmutableList}.
796     *
797     * @param elements the {@code Iterable} to add to the {@code ImmutableList}
798     * @return this {@code Builder} object
799     * @throws NullPointerException if {@code elements} is null or contains a null element
800     */
801    @CanIgnoreReturnValue
802    @Override
803    public Builder<E> add(E... elements) {
804      super.add(elements);
805      return this;
806    }
807
808    /**
809     * Adds each element of {@code elements} to the {@code ImmutableList}.
810     *
811     * @param elements the {@code Iterable} to add to the {@code ImmutableList}
812     * @return this {@code Builder} object
813     * @throws NullPointerException if {@code elements} is null or contains a null element
814     */
815    @CanIgnoreReturnValue
816    @Override
817    public Builder<E> addAll(Iterable<? extends E> elements) {
818      super.addAll(elements);
819      return this;
820    }
821
822    /**
823     * Adds each element of {@code elements} to the {@code ImmutableList}.
824     *
825     * @param elements the {@code Iterator} to add to the {@code ImmutableList}
826     * @return this {@code Builder} object
827     * @throws NullPointerException if {@code elements} is null or contains a null element
828     */
829    @CanIgnoreReturnValue
830    @Override
831    public Builder<E> addAll(Iterator<? extends E> elements) {
832      super.addAll(elements);
833      return this;
834    }
835
836    @CanIgnoreReturnValue
837    Builder<E> combine(Builder<E> other) {
838      addAll(other.contents, other.size);
839      return this;
840    }
841
842    /**
843     * Returns a newly-created {@code ImmutableList} based on the contents of the {@code Builder}.
844     */
845    @Override
846    public ImmutableList<E> build() {
847      forceCopy = true;
848      return asImmutableList(contents, size);
849    }
850  }
851
852  private static final long serialVersionUID = 0xcafebabe;
853}