Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2009 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.base.Preconditions;
     21 
     22 import java.util.Collections;
     23 import java.util.List;
     24 import java.util.ListIterator;
     25 
     26 import javax.annotation.Nullable;
     27 
     28 import static com.google.common.base.Preconditions.checkNotNull;
     29 
     30 /**
     31  * Implementation of {@link ImmutableList} with exactly one element.
     32  *
     33  * @author Hayward Chan
     34  */
     35 @GwtCompatible(serializable = true)
     36 @SuppressWarnings("serial") // uses writeReplace(), not default serialization
     37 final class SingletonImmutableList<E> extends ImmutableList<E> {
     38   final transient E element;
     39 
     40   SingletonImmutableList(E element) {
     41     this.element = checkNotNull(element);
     42   }
     43 
     44   public E get(int index) {
     45     Preconditions.checkElementIndex(index, 1);
     46     return element;
     47   }
     48 
     49   @Override public int indexOf(@Nullable Object object) {
     50     return element.equals(object) ? 0 : -1;
     51   }
     52 
     53   @Override public UnmodifiableIterator<E> iterator() {
     54     return Iterators.singletonIterator(element);
     55   }
     56 
     57   @Override public int lastIndexOf(@Nullable Object object) {
     58     return element.equals(object) ? 0 : -1;
     59   }
     60 
     61   public ListIterator<E> listIterator() {
     62     return listIterator(0);
     63   }
     64 
     65   public ListIterator<E> listIterator(final int start) {
     66     // suboptimal but not worth optimizing.
     67     return Collections.singletonList(element).listIterator(start);
     68   }
     69 
     70   public int size() {
     71     return 1;
     72   }
     73 
     74   @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
     75     Preconditions.checkPositionIndexes(fromIndex, toIndex, 1);
     76     return (fromIndex == toIndex) ? ImmutableList.<E>of() : this;
     77   }
     78 
     79   @Override public boolean contains(@Nullable Object object) {
     80     return element.equals(object);
     81   }
     82 
     83   @Override public boolean equals(Object object) {
     84     if (object == this) {
     85       return true;
     86     }
     87     if (object instanceof List) {
     88       List<?> that = (List<?>) object;
     89       return that.size() == 1 && element.equals(that.get(0));
     90     }
     91     return false;
     92   }
     93 
     94   @Override public int hashCode() {
     95     // not caching hash code since it could change if the element is mutable
     96     // in a way that modifies its hash code.
     97     return 31 + element.hashCode();
     98   }
     99 
    100   @Override public boolean isEmpty() {
    101     return false;
    102   }
    103 
    104   @Override public Object[] toArray() {
    105     return new Object[] { element };
    106   }
    107 
    108   @Override public <T> T[] toArray(T[] array) {
    109     if (array.length == 0) {
    110       array = ObjectArrays.newArray(array, 1);
    111     } else if (array.length > 1) {
    112       array[1] = null;
    113     }
    114     // Writes will produce ArrayStoreException when the toArray() doc requires.
    115     Object[] objectArray = array;
    116     objectArray[0] = element;
    117     return array;
    118   }
    119 }
    120