1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkNotNull;
20
21 import com.google.common.collect.Lists;
22
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.RandomAccess;
30
31 import javax.annotation.Nullable;
32
33
34
35
36
37
38
39 @SuppressWarnings("serial")
40 public abstract class ImmutableList<E> extends ImmutableCollection<E>
41 implements List<E>, RandomAccess {
42 static final ImmutableList<Object> EMPTY =
43 new RegularImmutableList<Object>(Collections.emptyList());
44
45 ImmutableList() {}
46
47
48 @SuppressWarnings("unchecked")
49 public static <E> ImmutableList<E> of() {
50 return (ImmutableList<E>) EMPTY;
51 }
52
53 public static <E> ImmutableList<E> of(E element) {
54 return new SingletonImmutableList<E>(element);
55 }
56
57 public static <E> ImmutableList<E> of(E e1, E e2) {
58 return new RegularImmutableList<E>(
59 ImmutableList.<E>nullCheckedList(e1, e2));
60 }
61
62 public static <E> ImmutableList<E> of(E e1, E e2, E e3) {
63 return new RegularImmutableList<E>(
64 ImmutableList.<E>nullCheckedList(e1, e2, e3));
65 }
66
67 public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) {
68 return new RegularImmutableList<E>(
69 ImmutableList.<E>nullCheckedList(e1, e2, e3, e4));
70 }
71
72 public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) {
73 return new RegularImmutableList<E>(
74 ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5));
75 }
76
77 public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
78 return new RegularImmutableList<E>(
79 ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5, e6));
80 }
81
82 public static <E> ImmutableList<E> of(
83 E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
84 return new RegularImmutableList<E>(
85 ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5, e6, e7));
86 }
87
88 public static <E> ImmutableList<E> of(
89 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
90 return new RegularImmutableList<E>(
91 ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5, e6, e7, e8));
92 }
93
94 public static <E> ImmutableList<E> of(
95 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
96 return new RegularImmutableList<E>(
97 ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5, e6, e7, e8, e9));
98 }
99
100 public static <E> ImmutableList<E> of(
101 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
102 return new RegularImmutableList<E>(ImmutableList.<E>nullCheckedList(
103 e1, e2, e3, e4, e5, e6, e7, e8, e9, e10));
104 }
105
106 public static <E> ImmutableList<E> of(
107 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {
108 return new RegularImmutableList<E>(ImmutableList.<E>nullCheckedList(
109 e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11));
110 }
111
112 public static <E> ImmutableList<E> of(
113 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11,
114 E e12, E... others) {
115 final int paramCount = 12;
116 Object[] array = new Object[paramCount + others.length];
117 arrayCopy(array, 0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12);
118 arrayCopy(array, paramCount, others);
119 return new RegularImmutableList<E>(ImmutableList.<E>nullCheckedList(array));
120 }
121
122 private static void arrayCopy(Object[] dest, int pos, Object... source) {
123 System.arraycopy(source, 0, dest, pos, source.length);
124 }
125
126 public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {
127 checkNotNull(elements);
128 return (elements instanceof Collection)
129 ? copyOf((Collection<? extends E>) elements)
130 : copyOf(elements.iterator());
131 }
132
133 public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
134 return copyFromCollection(Lists.newArrayList(elements));
135 }
136
137 public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
138 if (elements instanceof ImmutableCollection) {
139
140
141
142
143 @SuppressWarnings("unchecked")
144 ImmutableCollection<E> list = (ImmutableCollection<E>) elements;
145 return list.asList();
146 }
147 return copyFromCollection(elements);
148 }
149
150 public static <E> ImmutableList<E> copyOf(E[] elements) {
151 checkNotNull(elements);
152 return copyOf(Arrays.asList(elements));
153 }
154
155 private static <E> ImmutableList<E> copyFromCollection(
156 Collection<? extends E> collection) {
157 Object[] elements = collection.toArray();
158 switch (elements.length) {
159 case 0:
160 return of();
161 case 1:
162 @SuppressWarnings("unchecked")
163 ImmutableList<E> list = new SingletonImmutableList<E>((E) elements[0]);
164 return list;
165 default:
166 return new RegularImmutableList<E>(ImmutableList.<E>nullCheckedList(elements));
167 }
168 }
169
170
171
172 static <E> ImmutableList<E> unsafeDelegateList(List<? extends E> list) {
173 switch (list.size()) {
174 case 0:
175 return of();
176 case 1:
177 return new SingletonImmutableList<E>(list.iterator().next());
178 default:
179 @SuppressWarnings("unchecked")
180 List<E> castedList = (List<E>) list;
181 return new RegularImmutableList<E>(castedList);
182 }
183 }
184
185
186
187
188
189
190 @SuppressWarnings("unchecked")
191 static <E> ImmutableList<E> asImmutableList(Object[] elements) {
192 return unsafeDelegateList((List) Arrays.asList(elements));
193 }
194
195 private static <E> List<E> nullCheckedList(Object... array) {
196 for (int i = 0, len = array.length; i < len; i++) {
197 if (array[i] == null) {
198 throw new NullPointerException("at index " + i);
199 }
200 }
201 @SuppressWarnings("unchecked")
202 E[] castedArray = (E[]) array;
203 return Arrays.asList(castedArray);
204 }
205
206 @Override
207 public int indexOf(@Nullable Object object) {
208 return (object == null) ? -1 : Lists.indexOfImpl(this, object);
209 }
210
211 @Override
212 public int lastIndexOf(@Nullable Object object) {
213 return (object == null) ? -1 : Lists.lastIndexOfImpl(this, object);
214 }
215
216 public final boolean addAll(int index, Collection<? extends E> newElements) {
217 throw new UnsupportedOperationException();
218 }
219
220 public final E set(int index, E element) {
221 throw new UnsupportedOperationException();
222 }
223
224 public final void add(int index, E element) {
225 throw new UnsupportedOperationException();
226 }
227
228 public final E remove(int index) {
229 throw new UnsupportedOperationException();
230 }
231
232 @Override public UnmodifiableIterator<E> iterator() {
233 return listIterator();
234 }
235
236 @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
237 return unsafeDelegateList(Lists.subListImpl(this, fromIndex, toIndex));
238 }
239
240 @Override public UnmodifiableListIterator<E> listIterator() {
241 return listIterator(0);
242 }
243
244 @Override public UnmodifiableListIterator<E> listIterator(int index) {
245 return new AbstractIndexedListIterator<E>(size(), index) {
246 @Override
247 protected E get(int index) {
248 return ImmutableList.this.get(index);
249 }
250 };
251 }
252
253 @Override public ImmutableList<E> asList() {
254 return this;
255 }
256
257 @Override
258 public boolean equals(@Nullable Object obj) {
259 return Lists.equalsImpl(this, obj);
260 }
261
262 @Override
263 public int hashCode() {
264 return Lists.hashCodeImpl(this);
265 }
266
267 public ImmutableList<E> reverse() {
268 List<E> list = Lists.newArrayList(this);
269 Collections.reverse(list);
270 return unsafeDelegateList(list);
271 }
272
273 public static <E> Builder<E> builder() {
274 return new Builder<E>();
275 }
276
277 public static final class Builder<E> extends ImmutableCollection.Builder<E> {
278 private final ArrayList<E> contents;
279
280 public Builder() {
281 contents = Lists.newArrayList();
282 }
283
284 Builder(int capacity) {
285 contents = Lists.newArrayListWithCapacity(capacity);
286 }
287
288 @Override public Builder<E> add(E element) {
289 contents.add(checkNotNull(element));
290 return this;
291 }
292
293 @Override public Builder<E> addAll(Iterable<? extends E> elements) {
294 super.addAll(elements);
295 return this;
296 }
297
298 @Override public Builder<E> add(E... elements) {
299 checkNotNull(elements);
300 super.add(elements);
301 return this;
302 }
303
304 @Override public Builder<E> addAll(Iterator<? extends E> elements) {
305 super.addAll(elements);
306 return this;
307 }
308
309 @Override public ImmutableList<E> build() {
310 return copyOf(contents);
311 }
312 }
313 }