1/* 2 * Copyright (C) 2010 The Guava Authors 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 17package com.google.common.collect; 18import static com.google.common.base.Preconditions.checkNotNull; 19 20import com.google.common.annotations.GwtCompatible; 21 22import java.util.List; 23 24import javax.annotation.Nullable; 25 26/** 27 * A transforming wrapper around an ImmutableList. For internal use only. {@link 28 * #transform(Object)} must be functional. 29 * 30 * @author Louis Wasserman 31 */ 32@GwtCompatible 33@SuppressWarnings("serial") // uses writeReplace(), not default serialization 34abstract class TransformedImmutableList<D, E> extends ImmutableList<E> { 35 private class TransformedView extends TransformedImmutableList<D, E> { 36 TransformedView(ImmutableList<D> backingList) { 37 super(backingList); 38 } 39 40 @Override E transform(D d) { 41 return TransformedImmutableList.this.transform(d); 42 } 43 } 44 45 private transient final ImmutableList<D> backingList; 46 47 TransformedImmutableList(ImmutableList<D> backingList) { 48 this.backingList = checkNotNull(backingList); 49 } 50 51 abstract E transform(D d); 52 53 @Override public int indexOf(@Nullable Object object) { 54 if (object == null) { 55 return -1; 56 } 57 for (int i = 0; i < size(); i++) { 58 if (get(i).equals(object)) { 59 return i; 60 } 61 } 62 return -1; 63 } 64 65 @Override public int lastIndexOf(@Nullable Object object) { 66 if (object == null) { 67 return -1; 68 } 69 for (int i = size() - 1; i >= 0; i--) { 70 if (get(i).equals(object)) { 71 return i; 72 } 73 } 74 return -1; 75 } 76 77 @Override public E get(int index) { 78 return transform(backingList.get(index)); 79 } 80 81 @Override public UnmodifiableListIterator<E> listIterator(int index) { 82 return new AbstractIndexedListIterator<E>(size(), index) { 83 @Override protected E get(int index) { 84 return TransformedImmutableList.this.get(index); 85 } 86 }; 87 } 88 89 @Override public int size() { 90 return backingList.size(); 91 } 92 93 @Override public ImmutableList<E> subList(int fromIndex, int toIndex) { 94 return new TransformedView(backingList.subList(fromIndex, toIndex)); 95 } 96 97 @Override public boolean equals(@Nullable Object obj) { 98 if (obj == this) { 99 return true; 100 } 101 if (obj instanceof List) { 102 List<?> list = (List<?>) obj; 103 return size() == list.size() 104 && Iterators.elementsEqual(iterator(), list.iterator()); 105 } 106 return false; 107 } 108 109 @Override public int hashCode() { 110 int hashCode = 1; 111 for (E e : this) { 112 hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode()); 113 } 114 return hashCode; 115 } 116 117 @Override public Object[] toArray() { 118 return ObjectArrays.toArrayImpl(this); 119 } 120 121 @Override public <T> T[] toArray(T[] array) { 122 return ObjectArrays.toArrayImpl(this, array); 123 } 124 125 @Override boolean isPartialView() { 126 return true; 127 } 128} 129