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.checkElementIndex;
020    import static com.google.common.base.Preconditions.checkNotNull;
021    import static com.google.common.base.Preconditions.checkPositionIndex;
022    import static com.google.common.base.Preconditions.checkPositionIndexes;
023    import static com.google.common.collect.ObjectArrays.checkElementNotNull;
024    
025    import com.google.common.annotations.GwtCompatible;
026    
027    import java.io.InvalidObjectException;
028    import java.io.ObjectInputStream;
029    import java.io.Serializable;
030    import java.util.Collection;
031    import java.util.Collections;
032    import java.util.Iterator;
033    import java.util.List;
034    import java.util.RandomAccess;
035    
036    import javax.annotation.Nullable;
037    
038    /**
039     * A high-performance, immutable, random-access {@code List} implementation.
040     * Does not permit null elements.
041     *
042     * <p>Unlike {@link Collections#unmodifiableList}, which is a <i>view</i> of a
043     * separate collection that can still change, an instance of {@code
044     * ImmutableList} contains its own private data and will <i>never</i> change.
045     * {@code ImmutableList} is convenient for {@code public static final} lists
046     * ("constant lists") and also lets you easily make a "defensive copy" of a list
047     * provided to your class by a caller.
048     *
049     * <p><b>Note:</b> Although this class is not final, it cannot be subclassed as
050     * it has no public or protected constructors. Thus, instances of this type are
051     * guaranteed to be immutable.
052     *
053     * <p>See the Guava User Guide article on <a href=
054     * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
055     * immutable collections</a>.
056     *
057     * @see ImmutableMap
058     * @see ImmutableSet
059     * @author Kevin Bourrillion
060     * @since 2.0 (imported from Google Collections Library)
061     */
062    @GwtCompatible(serializable = true, emulated = true)
063    @SuppressWarnings("serial") // we're overriding default serialization
064    public abstract class ImmutableList<E> extends ImmutableCollection<E>
065        implements List<E>, RandomAccess {
066      /**
067       * Returns the empty immutable list. This set behaves and performs comparably
068       * to {@link Collections#emptyList}, and is preferable mainly for consistency
069       * and maintainability of your code.
070       */
071      // Casting to any type is safe because the list will never hold any elements.
072      @SuppressWarnings("unchecked")
073      public static <E> ImmutableList<E> of() {
074        return (ImmutableList<E>) EmptyImmutableList.INSTANCE;
075      }
076    
077      /**
078       * Returns an immutable list containing a single element. This list behaves
079       * and performs comparably to {@link Collections#singleton}, but will not
080       * accept a null element. It is preferable mainly for consistency and
081       * maintainability of your code.
082       *
083       * @throws NullPointerException if {@code element} is null
084       */
085      public static <E> ImmutableList<E> of(E element) {
086        return new SingletonImmutableList<E>(element);
087      }
088    
089      /**
090       * Returns an immutable list containing the given elements, in order.
091       *
092       * @throws NullPointerException if any element is null
093       */
094      public static <E> ImmutableList<E> of(E e1, E e2) {
095        return construct(e1, e2);
096      }
097    
098      /**
099       * Returns an immutable list containing the given elements, in order.
100       *
101       * @throws NullPointerException if any element is null
102       */
103      public static <E> ImmutableList<E> of(E e1, E e2, E e3) {
104        return construct(e1, e2, e3);
105      }
106    
107      /**
108       * Returns an immutable list containing the given elements, in order.
109       *
110       * @throws NullPointerException if any element is null
111       */
112      public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) {
113        return construct(e1, e2, e3, e4);
114      }
115    
116      /**
117       * Returns an immutable list containing the given elements, in order.
118       *
119       * @throws NullPointerException if any element is null
120       */
121      public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) {
122        return construct(e1, e2, e3, e4, e5);
123      }
124    
125      /**
126       * Returns an immutable list containing the given elements, in order.
127       *
128       * @throws NullPointerException if any element is null
129       */
130      public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
131        return construct(e1, e2, e3, e4, e5, e6);
132      }
133    
134      /**
135       * Returns an immutable list containing the given elements, in order.
136       *
137       * @throws NullPointerException if any element is null
138       */
139      public static <E> ImmutableList<E> of(
140          E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
141        return construct(e1, e2, e3, e4, e5, e6, e7);
142      }
143    
144      /**
145       * Returns an immutable list containing the given elements, in order.
146       *
147       * @throws NullPointerException if any element is null
148       */
149      public static <E> ImmutableList<E> of(
150          E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
151        return construct(e1, e2, e3, e4, e5, e6, e7, e8);
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(
160          E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
161        return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9);
162      }
163    
164      /**
165       * Returns an immutable list containing the given elements, in order.
166       *
167       * @throws NullPointerException if any element is null
168       */
169      public static <E> ImmutableList<E> of(
170          E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
171        return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
172      }
173    
174      /**
175       * Returns an immutable list containing the given elements, in order.
176       *
177       * @throws NullPointerException if any element is null
178       */
179      public static <E> ImmutableList<E> of(
180          E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {
181        return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11);
182      }
183    
184      // These go up to eleven. After that, you just get the varargs form, and
185      // whatever warnings might come along with it. :(
186    
187      /**
188       * Returns an immutable list containing the given elements, in order.
189       *
190       * @throws NullPointerException if any element is null
191       * @since 3.0 (source-compatible since 2.0)
192       */
193      public static <E> ImmutableList<E> of(
194          E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12,
195          E... others) {
196        Object[] array = new Object[12 + others.length];
197        array[0] = e1;
198        array[1] = e2;
199        array[2] = e3;
200        array[3] = e4;
201        array[4] = e5;
202        array[5] = e6;
203        array[6] = e7;
204        array[7] = e8;
205        array[8] = e9;
206        array[9] = e10;
207        array[10] = e11;
208        array[11] = e12;
209        System.arraycopy(others, 0, array, 12, others.length);
210        return construct(array);
211      }
212    
213      /**
214       * Returns an immutable list containing the given elements, in order. If
215       * {@code elements} is a {@link Collection}, this method behaves exactly as
216       * {@link #copyOf(Collection)}; otherwise, it behaves exactly as {@code
217       * copyOf(elements.iterator()}.
218       *
219       * @throws NullPointerException if any of {@code elements} is null
220       */
221      public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {
222        checkNotNull(elements); // TODO(kevinb): is this here only for GWT?
223        return (elements instanceof Collection)
224          ? copyOf(Collections2.cast(elements))
225          : copyOf(elements.iterator());
226      }
227    
228      /**
229       * Returns an immutable list containing the given elements, in order.
230       *
231       * <p>Despite the method name, this method attempts to avoid actually copying
232       * the data when it is safe to do so. The exact circumstances under which a
233       * copy will or will not be performed are undocumented and subject to change.
234       *
235       * <p>Note that if {@code list} is a {@code List<String>}, then {@code
236       * ImmutableList.copyOf(list)} returns an {@code ImmutableList<String>}
237       * containing each of the strings in {@code list}, while
238       * ImmutableList.of(list)} returns an {@code ImmutableList<List<String>>}
239       * containing one element (the given list itself).
240       *
241       * <p>This method is safe to use even when {@code elements} is a synchronized
242       * or concurrent collection that is currently being modified by another
243       * thread.
244       *
245       * @throws NullPointerException if any of {@code elements} is null
246       */
247      public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
248        if (elements instanceof ImmutableCollection) {
249          @SuppressWarnings("unchecked") // all supported methods are covariant
250          ImmutableList<E> list = ((ImmutableCollection<E>) elements).asList();
251          return list.isPartialView() ? copyFromCollection(list) : list;
252        }
253        return copyFromCollection(elements);
254      }
255    
256      /**
257       * Returns an immutable list containing the given elements, in order.
258       *
259       * @throws NullPointerException if any of {@code elements} is null
260       */
261      public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
262        // We special-case for 0 or 1 elements, but going further is madness.
263        if (!elements.hasNext()) {
264          return of();
265        }
266        E first = elements.next();
267        if (!elements.hasNext()) {
268          return of(first);
269        } else {
270          return new ImmutableList.Builder<E>()
271              .add(first)
272              .addAll(elements)
273              .build();
274        }
275      }
276    
277      /**
278       * Returns an immutable list containing the given elements, in order.
279       *
280       * @throws NullPointerException if any of {@code elements} is null
281       * @since 3.0
282       */
283      public static <E> ImmutableList<E> copyOf(E[] elements) {
284        switch (elements.length) {
285          case 0:
286            return ImmutableList.of();
287          case 1:
288            return new SingletonImmutableList<E>(elements[0]);
289          default:
290            return construct(elements.clone());
291        }
292      }
293    
294      /**
295       * Views the array as an immutable list.  The array must have only non-null {@code E} elements.
296       *
297       * <p>The array must be internally created.
298       */
299      static <E> ImmutableList<E> asImmutableList(Object[] elements) {
300        switch (elements.length) {
301          case 0:
302            return of();
303          case 1:
304            @SuppressWarnings("unchecked") // collection had only Es in it
305            ImmutableList<E> list = new SingletonImmutableList<E>((E) elements[0]);
306            return list;
307          default:
308            return construct(elements);
309        }
310      }
311    
312      private static <E> ImmutableList<E> copyFromCollection(
313          Collection<? extends E> collection) {
314        return asImmutableList(collection.toArray());
315      }
316    
317      /** {@code elements} has to be internally created array. */
318      private static <E> ImmutableList<E> construct(Object... elements) {
319        for (int i = 0; i < elements.length; i++) {
320          ObjectArrays.checkElementNotNull(elements[i], i);
321        }
322        return new RegularImmutableList<E>(elements);
323      }
324    
325      ImmutableList() {}
326    
327      // This declaration is needed to make List.iterator() and
328      // ImmutableCollection.iterator() consistent.
329      
330      @Override
331      public UnmodifiableIterator<E> iterator() {
332        return listIterator();
333      }
334    
335      public UnmodifiableListIterator<E> listIterator() {
336        return listIterator(0);
337      }
338    
339      public UnmodifiableListIterator<E> listIterator(int index) {
340        return new AbstractIndexedListIterator<E>(size(), index) {
341          
342          @Override
343          protected E get(int index) {
344            return ImmutableList.this.get(index);
345          }
346        };
347      }
348    
349      public int indexOf(@Nullable Object object) {
350        return (object == null) ? -1 : Lists.indexOfImpl(this, object);
351      }
352    
353      public int lastIndexOf(@Nullable Object object) {
354        return (object == null) ? -1 : Lists.lastIndexOfImpl(this, object);
355      }
356    
357      
358      @Override
359      public boolean contains(@Nullable Object object) {
360        return indexOf(object) >= 0;
361      }
362    
363      // constrain the return type to ImmutableList<E>
364    
365      /**
366       * Returns an immutable list of the elements between the specified {@code
367       * fromIndex}, inclusive, and {@code toIndex}, exclusive. (If {@code
368       * fromIndex} and {@code toIndex} are equal, the empty immutable list is
369       * returned.)
370       */
371      public ImmutableList<E> subList(int fromIndex, int toIndex) {
372        checkPositionIndexes(fromIndex, toIndex, size());
373        int length = toIndex - fromIndex;
374        switch (length) {
375          case 0:
376            return of();
377          case 1:
378            return of(get(fromIndex));
379          default:
380            return subListUnchecked(fromIndex, toIndex);
381        }
382      }
383    
384      /**
385       * Called by the default implementation of {@link #subList} when {@code
386       * toIndex - fromIndex > 1}, after index validation has already been
387       * performed.
388       */
389      ImmutableList<E> subListUnchecked(int fromIndex, int toIndex) {
390        return new SubList(fromIndex, toIndex - fromIndex);
391      }
392    
393      class SubList extends ImmutableList<E> {
394        transient final int offset;
395        transient final int length;
396    
397        SubList(int offset, int length) {
398          this.offset = offset;
399          this.length = length;
400        }
401    
402        public int size() {
403          return length;
404        }
405    
406        public E get(int index) {
407          checkElementIndex(index, length);
408          return ImmutableList.this.get(index + offset);
409        }
410    
411        
412        @Override
413        public ImmutableList<E> subList(int fromIndex, int toIndex) {
414          checkPositionIndexes(fromIndex, toIndex, length);
415          return ImmutableList.this.subList(fromIndex + offset, toIndex + offset);
416        }
417    
418        
419        @Override
420        boolean isPartialView() {
421          return true;
422        }
423      }
424    
425      /**
426       * Guaranteed to throw an exception and leave the list unmodified.
427       *
428       * @throws UnsupportedOperationException always
429       */
430      public final boolean addAll(int index, Collection<? extends E> newElements) {
431        throw new UnsupportedOperationException();
432      }
433    
434      /**
435       * Guaranteed to throw an exception and leave the list unmodified.
436       *
437       * @throws UnsupportedOperationException always
438       */
439      public final E set(int index, E element) {
440        throw new UnsupportedOperationException();
441      }
442    
443      /**
444       * Guaranteed to throw an exception and leave the list unmodified.
445       *
446       * @throws UnsupportedOperationException always
447       */
448      public final void add(int index, E element) {
449        throw new UnsupportedOperationException();
450      }
451    
452      /**
453       * Guaranteed to throw an exception and leave the list unmodified.
454       *
455       * @throws UnsupportedOperationException always
456       */
457      public final E remove(int index) {
458        throw new UnsupportedOperationException();
459      }
460    
461      /**
462       * Returns this list instance.
463       *
464       * @since 2.0
465       */
466      
467      @Override
468      public ImmutableList<E> asList() {
469        return this;
470      }
471    
472      /**
473       * Returns a view of this immutable list in reverse order. For example, {@code
474       * ImmutableList.of(1, 2, 3).reverse()} is equivalent to {@code
475       * ImmutableList.of(3, 2, 1)}.
476       *
477       * @return a view of this immutable list in reverse order
478       * @since 7.0
479       */
480      public ImmutableList<E> reverse() {
481        return new ReverseImmutableList<E>(this);
482      }
483    
484      private static class ReverseImmutableList<E> extends ImmutableList<E> {
485        private final transient ImmutableList<E> forwardList;
486        private final transient int size;
487    
488        ReverseImmutableList(ImmutableList<E> backingList) {
489          this.forwardList = backingList;
490          this.size = backingList.size();
491        }
492    
493        private int reverseIndex(int index) {
494          return (size - 1) - index;
495        }
496    
497        private int reversePosition(int index) {
498          return size - index;
499        }
500    
501        
502        @Override
503        public ImmutableList<E> reverse() {
504          return forwardList;
505        }
506    
507        
508        @Override
509        public boolean contains(@Nullable Object object) {
510          return forwardList.contains(object);
511        }
512    
513        
514        @Override
515        public boolean containsAll(Collection<?> targets) {
516          return forwardList.containsAll(targets);
517        }
518    
519        
520        @Override
521        public int indexOf(@Nullable Object object) {
522          int index = forwardList.lastIndexOf(object);
523          return (index >= 0) ? reverseIndex(index) : -1;
524        }
525    
526        
527        @Override
528        public int lastIndexOf(@Nullable Object object) {
529          int index = forwardList.indexOf(object);
530          return (index >= 0) ? reverseIndex(index) : -1;
531        }
532    
533        
534        @Override
535        public ImmutableList<E> subList(int fromIndex, int toIndex) {
536          checkPositionIndexes(fromIndex, toIndex, size);
537          return forwardList.subList(
538              reversePosition(toIndex), reversePosition(fromIndex)).reverse();
539        }
540    
541        public E get(int index) {
542          checkElementIndex(index, size);
543          return forwardList.get(reverseIndex(index));
544        }
545    
546        
547        @Override
548        public UnmodifiableListIterator<E> listIterator(int index) {
549          checkPositionIndex(index, size);
550          final UnmodifiableListIterator<E> forward =
551              forwardList.listIterator(reversePosition(index));
552          return new UnmodifiableListIterator<E>() {
553            public boolean hasNext() {
554              return forward.hasPrevious();
555            }
556    
557            public boolean hasPrevious() {
558              return forward.hasNext();
559            }
560    
561            public E next() {
562              return forward.previous();
563            }
564    
565            public int nextIndex() {
566              return reverseIndex(forward.previousIndex());
567            }
568    
569            public E previous() {
570              return forward.next();
571            }
572    
573            public int previousIndex() {
574              return reverseIndex(forward.nextIndex());
575            }
576          };
577        }
578    
579        public int size() {
580          return size;
581        }
582    
583        
584        @Override
585        public boolean isEmpty() {
586          return forwardList.isEmpty();
587        }
588    
589        
590        @Override
591        boolean isPartialView() {
592          return forwardList.isPartialView();
593        }
594      }
595    
596      
597      @Override
598      public boolean equals(Object obj) {
599        return Lists.equalsImpl(this, obj);
600      }
601    
602      
603      @Override
604      public int hashCode() {
605        return Lists.hashCodeImpl(this);
606      }
607    
608      /*
609       * Serializes ImmutableLists as their logical contents. This ensures that
610       * implementation types do not leak into the serialized representation.
611       */
612      private static class SerializedForm implements Serializable {
613        final Object[] elements;
614        SerializedForm(Object[] elements) {
615          this.elements = elements;
616        }
617        Object readResolve() {
618          return copyOf(elements);
619        }
620        private static final long serialVersionUID = 0;
621      }
622    
623      private void readObject(ObjectInputStream stream)
624          throws InvalidObjectException {
625        throw new InvalidObjectException("Use SerializedForm");
626      }
627    
628      
629      @Override
630      Object writeReplace() {
631        return new SerializedForm(toArray());
632      }
633    
634      /**
635       * Returns a new builder. The generated builder is equivalent to the builder
636       * created by the {@link Builder} constructor.
637       */
638      public static <E> Builder<E> builder() {
639        return new Builder<E>();
640      }
641    
642      /**
643       * A builder for creating immutable list instances, especially {@code public
644       * static final} lists ("constant lists"). Example: <pre>   {@code
645       *
646       *   public static final ImmutableList<Color> GOOGLE_COLORS
647       *       = new ImmutableList.Builder<Color>()
648       *           .addAll(WEBSAFE_COLORS)
649       *           .add(new Color(0, 191, 255))
650       *           .build();}</pre>
651       *
652       * Builder instances can be reused; it is safe to call {@link #build} multiple
653       * times to build multiple lists in series. Each new list contains all the
654       * elements of the ones created before it.
655       *
656       * @since 2.0 (imported from Google Collections Library)
657       */
658      public static final class Builder<E> extends ImmutableCollection.Builder<E> {
659        private Object[] contents;
660        private int size;
661    
662        /**
663         * Creates a new builder. The returned builder is equivalent to the builder
664         * generated by {@link ImmutableList#builder}.
665         */
666        public Builder() {
667          this(DEFAULT_INITIAL_CAPACITY);
668        }
669    
670        // TODO(user): consider exposing this
671        Builder(int capacity) {
672          this.contents = new Object[capacity];
673          this.size = 0;
674        }
675    
676        /**
677         * Expand capacity to allow the specified number of elements to be added.
678         */
679        Builder<E> expandFor(int count) {
680          int minCapacity = size + count;
681          if (contents.length < minCapacity) {
682            this.contents = ObjectArrays.arraysCopyOf(
683                this.contents, expandedCapacity(contents.length, minCapacity));
684          }
685          return this;
686        }
687    
688        /**
689         * Adds {@code element} to the {@code ImmutableList}.
690         *
691         * @param element the element to add
692         * @return this {@code Builder} object
693         * @throws NullPointerException if {@code element} is null
694         */
695        @Override
696        public Builder<E> add(E element) {
697          checkNotNull(element);
698          expandFor(1);
699          contents[size++] = element;
700          return this;
701        }
702    
703        /**
704         * Adds each element of {@code elements} to the {@code ImmutableList}.
705         *
706         * @param elements the {@code Iterable} to add to the {@code ImmutableList}
707         * @return this {@code Builder} object
708         * @throws NullPointerException if {@code elements} is null or contains a
709         *     null element
710         */
711        
712        @Override
713        public Builder<E> addAll(Iterable<? extends E> elements) {
714          if (elements instanceof Collection) {
715            Collection<?> collection = (Collection<?>) elements;
716            expandFor(collection.size());
717          }
718          super.addAll(elements);
719          return this;
720        }
721    
722        /**
723         * Adds each element of {@code elements} to the {@code ImmutableList}.
724         *
725         * @param elements the {@code Iterable} to add to the {@code ImmutableList}
726         * @return this {@code Builder} object
727         * @throws NullPointerException if {@code elements} is null or contains a
728         *     null element
729         */
730        @Override
731        public Builder<E> add(E... elements) {
732          for (int i = 0; i < elements.length; i++) {
733            checkElementNotNull(elements[i], i);
734          }
735          expandFor(elements.length);
736          System.arraycopy(elements, 0, contents, size, elements.length);
737          size += elements.length;
738          return this;
739        }
740    
741        /**
742         * Adds each element of {@code elements} to the {@code ImmutableList}.
743         *
744         * @param elements the {@code Iterable} to add to the {@code ImmutableList}
745         * @return this {@code Builder} object
746         * @throws NullPointerException if {@code elements} is null or contains a
747         *     null element
748         */
749        
750        @Override
751        public Builder<E> addAll(Iterator<? extends E> elements) {
752          super.addAll(elements);
753          return this;
754        }
755    
756        /**
757         * Returns a newly-created {@code ImmutableList} based on the contents of
758         * the {@code Builder}.
759         */
760        @Override
761        public ImmutableList<E> build() {
762          switch (size) {
763            case 0:
764              return of();
765            case 1:
766              @SuppressWarnings("unchecked") // guaranteed to be an E
767              E singleElement = (E) contents[0];
768              return of(singleElement);
769            default:
770              if (size == contents.length) {
771                // no need to copy; any further add operations on the builder will copy the buffer
772                return new RegularImmutableList<E>(contents);
773              } else {
774                return new RegularImmutableList<E>(ObjectArrays.arraysCopyOf(contents, size));
775              }
776          }
777        }
778      }
779    }