001    /*
002     * Copyright (C) 2007 Google Inc.
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.checkNotNull;
020    
021    import com.google.common.annotations.GwtCompatible;
022    
023    import java.io.InvalidObjectException;
024    import java.io.ObjectInputStream;
025    import java.io.Serializable;
026    import java.util.ArrayList;
027    import java.util.Collection;
028    import java.util.Collections;
029    import java.util.Iterator;
030    import java.util.List;
031    import java.util.RandomAccess;
032    
033    import javax.annotation.Nullable;
034    
035    /**
036     * A high-performance, immutable, random-access {@code List} implementation.
037     * Does not permit null elements.
038     *
039     * <p>Unlike {@link Collections#unmodifiableList}, which is a <i>view</i> of a
040     * separate collection that can still change, an instance of {@code
041     * ImmutableList} contains its own private data and will <i>never</i> change.
042     * {@code ImmutableList} is convenient for {@code public static final} lists
043     * ("constant lists") and also lets you easily make a "defensive copy" of a list
044     * provided to your class by a caller.
045     *
046     * <p><b>Note</b>: Although this class is not final, it cannot be subclassed as
047     * it has no public or protected constructors. Thus, instances of this type are
048     * guaranteed to be immutable.
049     *
050     * @see ImmutableMap
051     * @see ImmutableSet
052     * @author Kevin Bourrillion
053     * @since 2 (imported from Google Collections Library)
054     */
055    @GwtCompatible(serializable = true, emulated = true)
056    @SuppressWarnings("serial") // we're overriding default serialization
057    public abstract class ImmutableList<E> extends ImmutableCollection<E>
058        implements List<E>, RandomAccess {
059      /**
060       * Returns the empty immutable list. This set behaves and performs comparably
061       * to {@link Collections#emptyList}, and is preferable mainly for consistency
062       * and maintainability of your code.
063       */
064      // Casting to any type is safe because the list will never hold any elements.
065      @SuppressWarnings("unchecked")
066      public static <E> ImmutableList<E> of() {
067        return (ImmutableList<E>) EmptyImmutableList.INSTANCE;
068      }
069    
070      /**
071       * Returns an immutable list containing a single element. This list behaves
072       * and performs comparably to {@link Collections#singleton}, but will not
073       * accept a null element. It is preferable mainly for consistency and
074       * maintainability of your code.
075       *
076       * @throws NullPointerException if {@code element} is null
077       */
078      public static <E> ImmutableList<E> of(E element) {
079        return new SingletonImmutableList<E>(element);
080      }
081    
082      /**
083       * Returns an immutable list containing the given elements, in order.
084       *
085       * @throws NullPointerException if any element is null
086       */
087      public static <E> ImmutableList<E> of(E e1, E e2) {
088        return new RegularImmutableList<E>(copyIntoArray(e1, e2));
089      }
090    
091      /**
092       * Returns an immutable list containing the given elements, in order.
093       *
094       * @throws NullPointerException if any element is null
095       */
096      public static <E> ImmutableList<E> of(E e1, E e2, E e3) {
097        return new RegularImmutableList<E>(copyIntoArray(e1, e2, e3));
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, E e3, E e4) {
106        return new RegularImmutableList<E>(copyIntoArray(e1, e2, e3, e4));
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, E e4, E e5) {
115        return new RegularImmutableList<E>(copyIntoArray(e1, e2, e3, e4, e5));
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, E e5, E e6) {
124        return new RegularImmutableList<E>(copyIntoArray(e1, e2, e3, e4, e5, e6));
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(
133          E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
134        return new RegularImmutableList<E>(
135            copyIntoArray(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 new RegularImmutableList<E>(
146            copyIntoArray(e1, e2, e3, e4, e5, e6, e7, e8));
147      }
148    
149      /**
150       * Returns an immutable list containing the given elements, in order.
151       *
152       * @throws NullPointerException if any element is null
153       */
154      public static <E> ImmutableList<E> of(
155          E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
156        return new RegularImmutableList<E>(
157            copyIntoArray(e1, e2, e3, e4, e5, e6, e7, e8, e9));
158      }
159    
160      /**
161       * Returns an immutable list containing the given elements, in order.
162       *
163       * @throws NullPointerException if any element is null
164       */
165      public static <E> ImmutableList<E> of(
166          E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
167        return new RegularImmutableList<E>(
168            copyIntoArray(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10));
169      }
170    
171      /**
172       * Returns an immutable list containing the given elements, in order.
173       *
174       * @throws NullPointerException if any element is null
175       */
176      public static <E> ImmutableList<E> of(
177          E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {
178        return new RegularImmutableList<E>(
179            copyIntoArray(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11));
180      }
181    
182      // These go up to eleven. After that, you just get the varargs form, and
183      // whatever warnings might come along with it. :(
184    
185      /**
186       * Returns an immutable list containing the given elements, in order.
187       *
188       * @throws NullPointerException if any element is null
189       * @since 3 (source-compatible since release 2)
190       */
191      public static <E> ImmutableList<E> of(
192          E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12,
193          E... others) {
194        final int paramCount = 12;
195        Object[] array = new Object[paramCount + others.length];
196        copyIntoArray(array, 0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12);
197        copyIntoArray(array, paramCount, others);
198        return new RegularImmutableList<E>(array);
199      }
200    
201      /**
202       * Returns an immutable list containing the given elements, in order.
203       *
204       * @deprecated use {@link #copyOf(Object[])}
205       * @throws NullPointerException if any of {@code elements} is null
206       * @since 2 (changed from varargs in release 3)
207       */
208      @Deprecated
209      public static <E> ImmutableList<E> of(E[] elements) {
210        switch (elements.length) {
211          case 0:
212            return ImmutableList.of();
213          case 1:
214            return new SingletonImmutableList<E>(elements[0]);
215          default:
216            return new RegularImmutableList<E>(copyIntoArray(elements));
217        }
218      }
219    
220      /**
221       * Returns an immutable list containing the given elements, in order. If
222       * {@code elements} is a {@link Collection}, this method behaves exactly as
223       * {@link #copyOf(Collection)}; otherwise, it behaves exactly as {@code
224       * copyOf(elements.iterator()}.
225       *
226       * @throws NullPointerException if any of {@code elements} is null
227       */
228      @SuppressWarnings("unchecked") // bugs.sun.com/view_bug.do?bug_id=6558557
229      public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {
230        checkNotNull(elements);
231        return (elements instanceof Collection)
232          ? copyOf((Collection<? extends E>) elements)
233          : copyOf(elements.iterator());
234      }
235    
236      /**
237       * Returns an immutable list containing the given elements, in order.
238       *
239       * <p><b>Note:</b> Despite what the method name suggests, if {@code elements}
240       * is an {@code ImmutableList}, no copy will actually be performed, and the
241       * given list itself will be returned.
242       *
243       * <p>Note that if {@code list} is a {@code List<String>}, then {@code
244       * ImmutableList.copyOf(list)} returns an {@code ImmutableList<String>}
245       * containing each of the strings in {@code list}, while
246       * ImmutableList.of(list)} returns an {@code ImmutableList<List<String>>}
247       * containing one element (the given list itself).
248       *
249       * <p>This method is safe to use even when {@code elements} is a synchronized
250       * or concurrent collection that is currently being modified by another
251       * thread.
252       *
253       * @throws NullPointerException if any of {@code elements} is null
254       * @since 2 (Iterable overload existed previously)
255       */
256      public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
257        if (elements instanceof ImmutableCollection) {
258          /*
259           * TODO: When given an ImmutableList that's a sublist, copy the referenced
260           * portion of the array into a new array to save space?
261           */
262          @SuppressWarnings("unchecked") // all supported methods are covariant
263          ImmutableCollection<E> list = (ImmutableCollection<E>) elements;
264          return list.asList();
265        }
266        return copyFromCollection(elements);
267      }
268    
269      /**
270       * Returns an immutable list containing the given elements, in order.
271       *
272       * @throws NullPointerException if any of {@code elements} is null
273       */
274      public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
275        return copyFromCollection(Lists.newArrayList(elements));
276      }
277    
278      /**
279       * Returns an immutable list containing the given elements, in order.
280       *
281       * @throws NullPointerException if any of {@code elements} is null
282       * @since 3
283       */
284      public static <E> ImmutableList<E> copyOf(E[] elements) {
285        switch (elements.length) {
286          case 0:
287            return ImmutableList.of();
288          case 1:
289            return new SingletonImmutableList<E>(elements[0]);
290          default:
291            return new RegularImmutableList<E>(copyIntoArray(elements));
292        }
293      }
294    
295      private static <E> ImmutableList<E> copyFromCollection(
296          Collection<? extends E> collection) {
297        Object[] elements = collection.toArray();
298        switch (elements.length) {
299          case 0:
300            return of();
301          case 1:
302            @SuppressWarnings("unchecked") // collection had only Es in it
303            ImmutableList<E> list = new SingletonImmutableList<E>((E) elements[0]);
304            return list;
305          default:
306            return new RegularImmutableList<E>(copyIntoArray(elements));
307        }
308      }
309    
310      ImmutableList() {}
311    
312      // This declaration is needed to make List.iterator() and
313      // ImmutableCollection.iterator() consistent.
314      @Override public abstract UnmodifiableIterator<E> iterator();
315    
316      // Mark these two methods with @Nullable
317    
318      public abstract int indexOf(@Nullable Object object);
319    
320      public abstract int lastIndexOf(@Nullable Object object);
321    
322      // constrain the return type to ImmutableList<E>
323    
324      /**
325       * Returns an immutable list of the elements between the specified {@code
326       * fromIndex}, inclusive, and {@code toIndex}, exclusive. (If {@code
327       * fromIndex} and {@code toIndex} are equal, the empty immutable list is
328       * returned.)
329       */
330      public abstract ImmutableList<E> subList(int fromIndex, int toIndex);
331    
332      /**
333       * Guaranteed to throw an exception and leave the list unmodified.
334       *
335       * @throws UnsupportedOperationException always
336       */
337      public final boolean addAll(int index, Collection<? extends E> newElements) {
338        throw new UnsupportedOperationException();
339      }
340    
341      /**
342       * Guaranteed to throw an exception and leave the list unmodified.
343       *
344       * @throws UnsupportedOperationException always
345       */
346      public final E set(int index, E element) {
347        throw new UnsupportedOperationException();
348      }
349    
350      /**
351       * Guaranteed to throw an exception and leave the list unmodified.
352       *
353       * @throws UnsupportedOperationException always
354       */
355      public final void add(int index, E element) {
356        throw new UnsupportedOperationException();
357      }
358    
359      /**
360       * Guaranteed to throw an exception and leave the list unmodified.
361       *
362       * @throws UnsupportedOperationException always
363       */
364      public final E remove(int index) {
365        throw new UnsupportedOperationException();
366      }
367    
368      private static Object[] copyIntoArray(Object... source) {
369        return copyIntoArray(new Object[source.length], 0, source);
370      }
371    
372      private static Object[] copyIntoArray(Object[] dest, int pos,
373          Object... source) {
374        int index = pos;
375        for (Object element : source) {
376          if (element == null) {
377            throw new NullPointerException("at index " + index);
378          }
379          dest[index++] = element;
380        }
381        return dest;
382      }
383    
384      /**
385       * Returns this list instance.
386       *
387       * @since 2
388       */
389      @Override public ImmutableList<E> asList() {
390        return this;
391      }
392    
393      /*
394       * Serializes ImmutableLists as their logical contents. This ensures that
395       * implementation types do not leak into the serialized representation.
396       */
397      private static class SerializedForm implements Serializable {
398        final Object[] elements;
399        SerializedForm(Object[] elements) {
400          this.elements = elements;
401        }
402        Object readResolve() {
403          return copyOf(elements);
404        }
405        private static final long serialVersionUID = 0;
406      }
407    
408      private void readObject(ObjectInputStream stream)
409          throws InvalidObjectException {
410        throw new InvalidObjectException("Use SerializedForm");
411      }
412    
413      @Override Object writeReplace() {
414        return new SerializedForm(toArray());
415      }
416    
417      /**
418       * Returns a new builder. The generated builder is equivalent to the builder
419       * created by the {@link Builder} constructor.
420       */
421      public static <E> Builder<E> builder() {
422        return new Builder<E>();
423      }
424    
425      /**
426       * A builder for creating immutable list instances, especially
427       * {@code public static final} lists ("constant lists").
428       *
429       * <p>Example:
430       * <pre>   {@code
431       *   public static final ImmutableList<Color> GOOGLE_COLORS
432       *       = new ImmutableList.Builder<Color>()
433       *           .addAll(WEBSAFE_COLORS)
434       *           .add(new Color(0, 191, 255))
435       *           .build();}</pre>
436       *
437       * <p>Builder instances can be reused - it is safe to call {@link #build}
438       * multiple times to build multiple lists in series. Each new list
439       * contains the one created before it.
440       */
441      public static final class Builder<E> extends ImmutableCollection.Builder<E> {
442        private final ArrayList<E> contents = Lists.newArrayList();
443    
444        /**
445         * Creates a new builder. The returned builder is equivalent to the builder
446         * generated by {@link ImmutableList#builder}.
447         */
448        public Builder() {}
449    
450        /**
451         * Adds {@code element} to the {@code ImmutableList}.
452         *
453         * @param element the element to add
454         * @return this {@code Builder} object
455         * @throws NullPointerException if {@code element} is null
456         */
457        @Override public Builder<E> add(E element) {
458          contents.add(checkNotNull(element));
459          return this;
460        }
461    
462        /**
463         * Adds each element of {@code elements} to the {@code ImmutableList}.
464         *
465         * @param elements the {@code Iterable} to add to the {@code ImmutableList}
466         * @return this {@code Builder} object
467         * @throws NullPointerException if {@code elements} is null or contains a
468         *     null element
469         */
470        @Override public Builder<E> addAll(Iterable<? extends E> elements) {
471          if (elements instanceof Collection) {
472            Collection<?> collection = (Collection<?>) elements;
473            contents.ensureCapacity(contents.size() + collection.size());
474          }
475          super.addAll(elements);
476          return this;
477        }
478    
479        /**
480         * Adds each element of {@code elements} to the {@code ImmutableList}.
481         *
482         * @param elements the {@code Iterable} to add to the {@code ImmutableList}
483         * @return this {@code Builder} object
484         * @throws NullPointerException if {@code elements} is null or contains a
485         *     null element
486         */
487        @Override public Builder<E> add(E... elements) {
488          contents.ensureCapacity(contents.size() + elements.length);
489          super.add(elements);
490          return this;
491        }
492    
493        /**
494         * Adds each element of {@code elements} to the {@code ImmutableList}.
495         *
496         * @param elements the {@code Iterable} to add to the {@code ImmutableList}
497         * @return this {@code Builder} object
498         * @throws NullPointerException if {@code elements} is null or contains a
499         *     null element
500         */
501        @Override public Builder<E> addAll(Iterator<? extends E> elements) {
502          super.addAll(elements);
503          return this;
504        }
505    
506        /**
507         * Returns a newly-created {@code ImmutableList} based on the contents of
508         * the {@code Builder}.
509         */
510        @Override public ImmutableList<E> build() {
511          return copyOf(contents);
512        }
513      }
514    }
515