Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2007 Google Inc.
      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 
     17 package com.google.common.collect;
     18 
     19 import com.google.common.annotations.GwtCompatible;
     20 import com.google.common.annotations.VisibleForTesting;
     21 import com.google.common.base.Function;
     22 
     23 import java.io.Serializable;
     24 import java.util.AbstractList;
     25 import java.util.AbstractSequentialList;
     26 import java.util.ArrayList;
     27 import java.util.Arrays;
     28 import java.util.Collection;
     29 import java.util.Collections;
     30 import java.util.Iterator;
     31 import java.util.LinkedList;
     32 import java.util.List;
     33 import java.util.ListIterator;
     34 import java.util.RandomAccess;
     35 
     36 import javax.annotation.Nullable;
     37 
     38 import static com.google.common.base.Preconditions.checkArgument;
     39 import static com.google.common.base.Preconditions.checkElementIndex;
     40 import static com.google.common.base.Preconditions.checkNotNull;
     41 
     42 /**
     43  * Static utility methods pertaining to {@link List} instances. Also see this
     44  * class's counterparts {@link Sets} and {@link Maps}.
     45  *
     46  * @author Kevin Bourrillion
     47  * @author Mike Bostock
     48  * @since 2010.01.04 <b>stable</b> (imported from Google Collections Library)
     49  */
     50 @GwtCompatible
     51 public final class Lists {
     52   private Lists() {}
     53 
     54   // ArrayList
     55 
     56   /**
     57    * Creates a <i>mutable</i>, empty {@code ArrayList} instance.
     58    *
     59    * <p><b>Note:</b> if mutability is not required, use {@link
     60    * ImmutableList#of()} instead.
     61    *
     62    * @return a new, empty {@code ArrayList}
     63    */
     64   @GwtCompatible(serializable = true)
     65   public static <E> ArrayList<E> newArrayList() {
     66     return new ArrayList<E>();
     67   }
     68 
     69   /**
     70    * Creates a <i>mutable</i> {@code ArrayList} instance containing the given
     71    * elements.
     72    *
     73    * <p><b>Note:</b> if mutability is not required and the elements are
     74    * non-null, use {@link ImmutableList#of(Object[])} instead.
     75    *
     76    * @param elements the elements that the list should contain, in order
     77    * @return a new {@code ArrayList} containing those elements
     78    */
     79   @GwtCompatible(serializable = true)
     80   public static <E> ArrayList<E> newArrayList(E... elements) {
     81     checkNotNull(elements); // for GWT
     82     // Avoid integer overflow when a large array is passed in
     83     int capacity = computeArrayListCapacity(elements.length);
     84     ArrayList<E> list = new ArrayList<E>(capacity);
     85     Collections.addAll(list, elements);
     86     return list;
     87   }
     88 
     89   @VisibleForTesting static int computeArrayListCapacity(int arraySize) {
     90     checkArgument(arraySize >= 0);
     91 
     92     // TODO: Figure out the right behavior, and document it
     93     return (int) Math.min(5L + arraySize + (arraySize / 10), Integer.MAX_VALUE);
     94   }
     95 
     96   /**
     97    * Creates a <i>mutable</i> {@code ArrayList} instance containing the given
     98    * elements.
     99    *
    100    * <p><b>Note:</b> if mutability is not required and the elements are
    101    * non-null, use {@link ImmutableList#copyOf(Iterator)} instead.
    102    *
    103    * @param elements the elements that the list should contain, in order
    104    * @return a new {@code ArrayList} containing those elements
    105    */
    106   @GwtCompatible(serializable = true)
    107   public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {
    108     checkNotNull(elements); // for GWT
    109     // Let ArrayList's sizing logic work, if possible
    110     if (elements instanceof Collection) {
    111       @SuppressWarnings("unchecked")
    112       Collection<? extends E> collection = (Collection<? extends E>) elements;
    113       return new ArrayList<E>(collection);
    114     } else {
    115       return newArrayList(elements.iterator());
    116     }
    117   }
    118 
    119   /**
    120    * Creates a <i>mutable</i> {@code ArrayList} instance containing the given
    121    * elements.
    122    *
    123    * <p><b>Note:</b> if mutability is not required and the elements are
    124    * non-null, use {@link ImmutableList#copyOf(Iterator)} instead.
    125    *
    126    * @param elements the elements that the list should contain, in order
    127    * @return a new {@code ArrayList} containing those elements
    128    */
    129   @GwtCompatible(serializable = true)
    130   public static <E> ArrayList<E> newArrayList(Iterator<? extends E> elements) {
    131     checkNotNull(elements); // for GWT
    132     ArrayList<E> list = newArrayList();
    133     while (elements.hasNext()) {
    134       list.add(elements.next());
    135     }
    136     return list;
    137   }
    138 
    139   /**
    140    * Creates an {@code ArrayList} instance backed by an array of the
    141    * <i>exact</i> size specified; equivalent to
    142    * {@link ArrayList#ArrayList(int)}.
    143    *
    144    * <p><b>Note:</b> if you know the exact size your list will be, consider
    145    * using a fixed-size list ({@link Arrays#asList(Object[])}) or an {@link
    146    * ImmutableList} instead of a growable {@link ArrayList}.
    147    *
    148    * <p><b>Note:</b> If you have only an <i>estimate</i> of the eventual size of
    149    * the list, consider padding this estimate by a suitable amount, or simply
    150    * use {@link #newArrayListWithExpectedSize(int)} instead.
    151    *
    152    * @param initialArraySize the exact size of the initial backing array for
    153    *     the returned array list ({@code ArrayList} documentation calls this
    154    *     value the "capacity")
    155    * @return a new, empty {@code ArrayList} which is guaranteed not to resize
    156    *     itself unless its size reaches {@code initialArraySize + 1}
    157    * @throws IllegalArgumentException if {@code initialArraySize} is negative
    158    */
    159   @GwtCompatible(serializable = true)
    160   public static <E> ArrayList<E> newArrayListWithCapacity(
    161       int initialArraySize) {
    162     return new ArrayList<E>(initialArraySize);
    163   }
    164 
    165   /**
    166    * Creates an {@code ArrayList} instance sized appropriately to hold an
    167    * <i>estimated</i> number of elements without resizing. A small amount of
    168    * padding is added in case the estimate is low.
    169    *
    170    * <p><b>Note:</b> If you know the <i>exact</i> number of elements the list
    171    * will hold, or prefer to calculate your own amount of padding, refer to
    172    * {@link #newArrayListWithCapacity(int)}.
    173    *
    174    * @param estimatedSize an estimate of the eventual {@link List#size()} of
    175    *     the new list
    176    * @return a new, empty {@code ArrayList}, sized appropriately to hold the
    177    *     estimated number of elements
    178    * @throws IllegalArgumentException if {@code estimatedSize} is negative
    179    */
    180   @GwtCompatible(serializable = true)
    181   public static <E> ArrayList<E> newArrayListWithExpectedSize(
    182       int estimatedSize) {
    183     return new ArrayList<E>(computeArrayListCapacity(estimatedSize));
    184   }
    185 
    186   // LinkedList
    187 
    188   /**
    189    * Creates an empty {@code LinkedList} instance.
    190    *
    191    * <p><b>Note:</b> if you need an immutable empty {@link List}, use
    192    * {@link Collections#emptyList} instead.
    193    *
    194    * @return a new, empty {@code LinkedList}
    195    */
    196   @GwtCompatible(serializable = true)
    197   public static <E> LinkedList<E> newLinkedList() {
    198     return new LinkedList<E>();
    199   }
    200 
    201   /**
    202    * Creates a {@code LinkedList} instance containing the given elements.
    203    *
    204    * @param elements the elements that the list should contain, in order
    205    * @return a new {@code LinkedList} containing those elements
    206    */
    207   @GwtCompatible(serializable = true)
    208   public static <E> LinkedList<E> newLinkedList(
    209       Iterable<? extends E> elements) {
    210     LinkedList<E> list = newLinkedList();
    211     for (E element : elements) {
    212       list.add(element);
    213     }
    214     return list;
    215   }
    216 
    217   /**
    218    * Returns an unmodifiable list containing the specified first element and
    219    * backed by the specified array of additional elements. Changes to the {@code
    220    * rest} array will be reflected in the returned list. Unlike {@link
    221    * Arrays#asList}, the returned list is unmodifiable.
    222    *
    223    * <p>This is useful when a varargs method needs to use a signature such as
    224    * {@code (Foo firstFoo, Foo... moreFoos)}, in order to avoid overload
    225    * ambiguity or to enforce a minimum argument count.
    226    *
    227    * <p>The returned list is serializable and implements {@link RandomAccess}.
    228    *
    229    * @param first the first element
    230    * @param rest an array of additional elements, possibly empty
    231    * @return an unmodifiable list containing the specified elements
    232    */
    233   public static <E> List<E> asList(@Nullable E first, E[] rest) {
    234     return new OnePlusArrayList<E>(first, rest);
    235   }
    236 
    237   /** @see Lists#asList(Object, Object[]) */
    238   private static class OnePlusArrayList<E> extends AbstractList<E>
    239       implements Serializable, RandomAccess {
    240     final E first;
    241     final E[] rest;
    242 
    243     OnePlusArrayList(@Nullable E first, E[] rest) {
    244       this.first = first;
    245       this.rest = checkNotNull(rest);
    246     }
    247     @Override public int size() {
    248       return rest.length + 1;
    249     }
    250     @Override public E get(int index) {
    251       // check explicitly so the IOOBE will have the right message
    252       checkElementIndex(index, size());
    253       return (index == 0) ? first : rest[index - 1];
    254     }
    255     private static final long serialVersionUID = 0;
    256   }
    257 
    258   /**
    259    * Returns an unmodifiable list containing the specified first and second
    260    * element, and backed by the specified array of additional elements. Changes
    261    * to the {@code rest} array will be reflected in the returned list. Unlike
    262    * {@link Arrays#asList}, the returned list is unmodifiable.
    263    *
    264    * <p>This is useful when a varargs method needs to use a signature such as
    265    * {@code (Foo firstFoo, Foo secondFoo, Foo... moreFoos)}, in order to avoid
    266    * overload ambiguity or to enforce a minimum argument count.
    267    *
    268    * <p>The returned list is serializable and implements {@link RandomAccess}.
    269    *
    270    * @param first the first element
    271    * @param second the second element
    272    * @param rest an array of additional elements, possibly empty
    273    * @return an unmodifiable list containing the specified elements
    274    */
    275   public static <E> List<E> asList(
    276       @Nullable E first, @Nullable E second, E[] rest) {
    277     return new TwoPlusArrayList<E>(first, second, rest);
    278   }
    279 
    280   /** @see Lists#asList(Object, Object, Object[]) */
    281   private static class TwoPlusArrayList<E> extends AbstractList<E>
    282       implements Serializable, RandomAccess {
    283     final E first;
    284     final E second;
    285     final E[] rest;
    286 
    287     TwoPlusArrayList(@Nullable E first, @Nullable E second, E[] rest) {
    288       this.first = first;
    289       this.second = second;
    290       this.rest = checkNotNull(rest);
    291     }
    292     @Override public int size() {
    293       return rest.length + 2;
    294     }
    295     @Override public E get(int index) {
    296       switch (index) {
    297         case 0:
    298           return first;
    299         case 1:
    300           return second;
    301         default:
    302           // check explicitly so the IOOBE will have the right message
    303           checkElementIndex(index, size());
    304           return rest[index - 2];
    305       }
    306     }
    307     private static final long serialVersionUID = 0;
    308   }
    309 
    310   /**
    311    * Returns a list that applies {@code function} to each element of {@code
    312    * fromList}. The returned list is a transformed view of {@code fromList};
    313    * changes to {@code fromList} will be reflected in the returned list and vice
    314    * versa.
    315    *
    316    * <p>Since functions are not reversible, the transform is one-way and new
    317    * items cannot be stored in the returned list. The {@code add},
    318    * {@code addAll} and {@code set} methods are unsupported in the returned
    319    * list.
    320    *
    321    * <p>The function is applied lazily, invoked when needed. This is necessary
    322    * for the returned list to be a view, but it means that the function will be
    323    * applied many times for bulk operations like {@link List#contains} and
    324    * {@link List#hashCode}. For this to perform well, {@code function} should be
    325    * fast. To avoid lazy evaluation when the returned list doesn't need to be a
    326    * view, copy the returned list into a new list of your choosing.
    327    *
    328    * <p>If {@code fromList} implements {@link RandomAccess}, so will the
    329    * returned list. The returned list always implements {@link Serializable},
    330    * but serialization will succeed only when {@code fromList} and
    331    * {@code function} are serializable. The returned list is threadsafe if the
    332    * supplied list and function are.
    333    */
    334   public static <F, T> List<T> transform(
    335       List<F> fromList, Function<? super F, ? extends T> function) {
    336     return (fromList instanceof RandomAccess)
    337         ? new TransformingRandomAccessList<F, T>(fromList, function)
    338         : new TransformingSequentialList<F, T>(fromList, function);
    339   }
    340 
    341   /**
    342    * Implementation of a sequential transforming list.
    343    *
    344    * @see Lists#transform
    345    */
    346   private static class TransformingSequentialList<F, T>
    347       extends AbstractSequentialList<T> implements Serializable {
    348     final List<F> fromList;
    349     final Function<? super F, ? extends T> function;
    350 
    351     TransformingSequentialList(
    352         List<F> fromList, Function<? super F, ? extends T> function) {
    353       this.fromList = checkNotNull(fromList);
    354       this.function = checkNotNull(function);
    355     }
    356     /**
    357      * The default implementation inherited is based on iteration and removal of
    358      * each element which can be overkill. That's why we forward this call
    359      * directly to the backing list.
    360      */
    361     @Override public void clear() {
    362       fromList.clear();
    363     }
    364     @Override public int size() {
    365       return fromList.size();
    366     }
    367     @Override public ListIterator<T> listIterator(final int index) {
    368       final ListIterator<F> delegate = fromList.listIterator(index);
    369       return new ListIterator<T>() {
    370         public void add(T e) {
    371           throw new UnsupportedOperationException();
    372         }
    373 
    374         public boolean hasNext() {
    375           return delegate.hasNext();
    376         }
    377 
    378         public boolean hasPrevious() {
    379           return delegate.hasPrevious();
    380         }
    381 
    382         public T next() {
    383           return function.apply(delegate.next());
    384         }
    385 
    386         public int nextIndex() {
    387           return delegate.nextIndex();
    388         }
    389 
    390         public T previous() {
    391           return function.apply(delegate.previous());
    392         }
    393 
    394         public int previousIndex() {
    395           return delegate.previousIndex();
    396         }
    397 
    398         public void remove() {
    399           delegate.remove();
    400         }
    401 
    402         public void set(T e) {
    403           throw new UnsupportedOperationException("not supported");
    404         }
    405       };
    406     }
    407 
    408     private static final long serialVersionUID = 0;
    409   }
    410 
    411   /**
    412    * Implementation of a transforming random access list. We try to make as many
    413    * of these methods pass-through to the source list as possible so that the
    414    * performance characteristics of the source list and transformed list are
    415    * similar.
    416    *
    417    * @see Lists#transform
    418    */
    419   private static class TransformingRandomAccessList<F, T>
    420       extends AbstractList<T> implements RandomAccess, Serializable {
    421     final List<F> fromList;
    422     final Function<? super F, ? extends T> function;
    423 
    424     TransformingRandomAccessList(
    425         List<F> fromList, Function<? super F, ? extends T> function) {
    426       this.fromList = checkNotNull(fromList);
    427       this.function = checkNotNull(function);
    428     }
    429     @Override public void clear() {
    430       fromList.clear();
    431     }
    432     @Override public T get(int index) {
    433       return function.apply(fromList.get(index));
    434     }
    435     @Override public boolean isEmpty() {
    436       return fromList.isEmpty();
    437     }
    438     @Override public T remove(int index) {
    439       return function.apply(fromList.remove(index));
    440     }
    441     @Override public int size() {
    442       return fromList.size();
    443     }
    444     private static final long serialVersionUID = 0;
    445   }
    446 
    447   /**
    448    * Returns consecutive {@linkplain List#subList(int, int) sublists} of a list,
    449    * each of the same size (the final list may be smaller). For example,
    450    * partitioning a list containing {@code [a, b, c, d, e]} with a partition
    451    * size of 3 yields {@code [[a, b, c], [d, e]]} -- an outer list containing
    452    * two inner lists of three and two elements, all in the original order.
    453    *
    454    * <p>The outer list is unmodifiable, but reflects the latest state of the
    455    * source list. The inner lists are sublist views of the original list,
    456    * produced on demand using {@link List#subList(int, int)}, and are subject
    457    * to all the usual caveats about modification as explained in that API.
    458    *
    459    * @param list the list to return consecutive sublists of
    460    * @param size the desired size of each sublist (the last may be
    461    *     smaller)
    462    * @return a list of consecutive sublists
    463    * @throws IllegalArgumentException if {@code partitionSize} is nonpositive
    464    */
    465   public static <T> List<List<T>> partition(List<T> list, int size) {
    466     checkNotNull(list);
    467     checkArgument(size > 0);
    468     return (list instanceof RandomAccess)
    469         ? new RandomAccessPartition<T>(list, size)
    470         : new Partition<T>(list, size);
    471   }
    472 
    473   private static class Partition<T> extends AbstractList<List<T>> {
    474     final List<T> list;
    475     final int size;
    476 
    477     Partition(List<T> list, int size) {
    478       this.list = list;
    479       this.size = size;
    480     }
    481 
    482     @Override public List<T> get(int index) {
    483       int listSize = size();
    484       checkElementIndex(index, listSize);
    485       int start = index * size;
    486       int end = Math.min(start + size, list.size());
    487       return Platform.subList(list, start, end);
    488     }
    489 
    490     @Override public int size() {
    491       return (list.size() + size - 1) / size;
    492     }
    493 
    494     @Override public boolean isEmpty() {
    495       return list.isEmpty();
    496     }
    497   }
    498 
    499   private static class RandomAccessPartition<T> extends Partition<T>
    500       implements RandomAccess {
    501     RandomAccessPartition(List<T> list, int size) {
    502       super(list, size);
    503     }
    504   }
    505 }
    506