001 /*
002 * Copyright (C) 2008 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 com.google.common.annotations.GwtCompatible;
020 import com.google.common.annotations.VisibleForTesting;
021
022 import java.io.Serializable;
023 import java.util.Collection;
024 import java.util.Iterator;
025
026 import javax.annotation.Nullable;
027
028 /**
029 * An immutable collection. Does not permit null elements.
030 *
031 * <p>In addition to the {@link Collection} methods, this class has an {@link
032 * #asList()} method, which returns a list view of the collection's elements.
033 *
034 * <p><b>Note:</b> Although this class is not final, it cannot be subclassed
035 * outside of this package as it has no public or protected constructors. Thus,
036 * instances of this type are guaranteed to be immutable.
037 *
038 * @author Jesse Wilson
039 * @since 2.0 (imported from Google Collections Library)
040 */
041 @GwtCompatible(emulated = true)
042 @SuppressWarnings("serial") // we're overriding default serialization
043 public abstract class ImmutableCollection<E>
044 implements Collection<E>, Serializable {
045 static final ImmutableCollection<Object> EMPTY_IMMUTABLE_COLLECTION
046 = new EmptyImmutableCollection();
047
048 ImmutableCollection() {}
049
050 /**
051 * Returns an unmodifiable iterator across the elements in this collection.
052 */
053 public abstract UnmodifiableIterator<E> iterator();
054
055 public Object[] toArray() {
056 return ObjectArrays.toArrayImpl(this);
057 }
058
059 public <T> T[] toArray(T[] other) {
060 return ObjectArrays.toArrayImpl(this, other);
061 }
062
063 public boolean contains(@Nullable Object object) {
064 return object != null && Iterators.contains(iterator(), object);
065 }
066
067 public boolean containsAll(Collection<?> targets) {
068 return Collections2.containsAllImpl(this, targets);
069 }
070
071 public boolean isEmpty() {
072 return size() == 0;
073 }
074
075
076 @Override
077 public String toString() {
078 return Collections2.toStringImpl(this);
079 }
080
081 /**
082 * Guaranteed to throw an exception and leave the collection unmodified.
083 *
084 * @throws UnsupportedOperationException always
085 */
086 public final boolean add(E e) {
087 throw new UnsupportedOperationException();
088 }
089
090 /**
091 * Guaranteed to throw an exception and leave the collection unmodified.
092 *
093 * @throws UnsupportedOperationException always
094 */
095 public final boolean remove(Object object) {
096 throw new UnsupportedOperationException();
097 }
098
099 /**
100 * Guaranteed to throw an exception and leave the collection unmodified.
101 *
102 * @throws UnsupportedOperationException always
103 */
104 public final boolean addAll(Collection<? extends E> newElements) {
105 throw new UnsupportedOperationException();
106 }
107
108 /**
109 * Guaranteed to throw an exception and leave the collection unmodified.
110 *
111 * @throws UnsupportedOperationException always
112 */
113 public final boolean removeAll(Collection<?> oldElements) {
114 throw new UnsupportedOperationException();
115 }
116
117 /**
118 * Guaranteed to throw an exception and leave the collection unmodified.
119 *
120 * @throws UnsupportedOperationException always
121 */
122 public final boolean retainAll(Collection<?> elementsToKeep) {
123 throw new UnsupportedOperationException();
124 }
125
126 /**
127 * Guaranteed to throw an exception and leave the collection unmodified.
128 *
129 * @throws UnsupportedOperationException always
130 */
131 public final void clear() {
132 throw new UnsupportedOperationException();
133 }
134
135 /*
136 * TODO(kevinb): Restructure code so ImmutableList doesn't contain this
137 * variable, which it doesn't use.
138 */
139 private transient ImmutableList<E> asList;
140
141 /**
142 * Returns a list view of the collection.
143 *
144 * @since 2.0
145 */
146 public ImmutableList<E> asList() {
147 ImmutableList<E> list = asList;
148 return (list == null) ? (asList = createAsList()) : list;
149 }
150
151 ImmutableList<E> createAsList() {
152 switch (size()) {
153 case 0:
154 return ImmutableList.of();
155 case 1:
156 return ImmutableList.of(iterator().next());
157 default:
158 return new RegularImmutableAsList<E>(this, toArray());
159 }
160 }
161
162 abstract boolean isPartialView();
163
164 private static class EmptyImmutableCollection
165 extends ImmutableCollection<Object> {
166 public int size() {
167 return 0;
168 }
169
170
171 @Override
172 public boolean isEmpty() {
173 return true;
174 }
175
176
177 @Override
178 public boolean contains(@Nullable Object object) {
179 return false;
180 }
181
182 @Override
183 public UnmodifiableIterator<Object> iterator() {
184 return Iterators.EMPTY_LIST_ITERATOR;
185 }
186
187 private static final Object[] EMPTY_ARRAY = new Object[0];
188
189
190 @Override
191 public Object[] toArray() {
192 return EMPTY_ARRAY;
193 }
194
195
196 @Override
197 public <T> T[] toArray(T[] array) {
198 if (array.length > 0) {
199 array[0] = null;
200 }
201 return array;
202 }
203
204
205 @Override
206 ImmutableList<Object> createAsList() {
207 return ImmutableList.of();
208 }
209
210
211 @Override
212 boolean isPartialView() {
213 return false;
214 }
215 }
216
217 /**
218 * Nonempty collection stored in an array.
219 */
220 private static class ArrayImmutableCollection<E>
221 extends ImmutableCollection<E> {
222 private final E[] elements;
223
224 ArrayImmutableCollection(E[] elements) {
225 this.elements = elements;
226 }
227
228 public int size() {
229 return elements.length;
230 }
231
232
233 @Override
234 public boolean isEmpty() {
235 return false;
236 }
237
238
239 @Override
240 public UnmodifiableIterator<E> iterator() {
241 return Iterators.forArray(elements);
242 }
243
244
245 @Override
246 ImmutableList<E> createAsList() {
247 return elements.length == 1 ? new SingletonImmutableList<E>(elements[0])
248 : new RegularImmutableList<E>(elements);
249 }
250
251
252 @Override
253 boolean isPartialView() {
254 return false;
255 }
256 }
257
258 /*
259 * Serializes ImmutableCollections as their logical contents. This ensures
260 * that implementation types do not leak into the serialized representation.
261 */
262 private static class SerializedForm implements Serializable {
263 final Object[] elements;
264 SerializedForm(Object[] elements) {
265 this.elements = elements;
266 }
267 Object readResolve() {
268 return elements.length == 0
269 ? EMPTY_IMMUTABLE_COLLECTION
270 : new ArrayImmutableCollection<Object>(Platform.clone(elements));
271 }
272 private static final long serialVersionUID = 0;
273 }
274
275 Object writeReplace() {
276 return new SerializedForm(toArray());
277 }
278
279 /**
280 * Abstract base class for builders of {@link ImmutableCollection} types.
281 *
282 * @since 10.0
283 */
284 public abstract static class Builder<E> {
285 static final int DEFAULT_INITIAL_CAPACITY = 4;
286
287 @VisibleForTesting
288 static int expandedCapacity(int oldCapacity, int minCapacity) {
289 if (minCapacity < 0) {
290 throw new AssertionError("cannot store more than MAX_VALUE elements");
291 }
292 // careful of overflow!
293 int newCapacity = oldCapacity + (oldCapacity >> 1) + 1;
294 if (newCapacity < minCapacity) {
295 newCapacity = Integer.highestOneBit(minCapacity - 1) << 1;
296 }
297 if (newCapacity < 0) {
298 newCapacity = Integer.MAX_VALUE;
299 // guaranteed to be >= newCapacity
300 }
301 return newCapacity;
302 }
303
304 Builder() {
305 }
306
307 /**
308 * Adds {@code element} to the {@code ImmutableCollection} being built.
309 *
310 * <p>Note that each builder class covariantly returns its own type from
311 * this method.
312 *
313 * @param element the element to add
314 * @return this {@code Builder} instance
315 * @throws NullPointerException if {@code element} is null
316 */
317 public abstract Builder<E> add(E element);
318
319 /**
320 * Adds each element of {@code elements} to the {@code ImmutableCollection}
321 * being built.
322 *
323 * <p>Note that each builder class overrides this method in order to
324 * covariantly return its own type.
325 *
326 * @param elements the elements to add
327 * @return this {@code Builder} instance
328 * @throws NullPointerException if {@code elements} is null or contains a
329 * null element
330 */
331 public Builder<E> add(E... elements) {
332 for (E element : elements) {
333 add(element);
334 }
335 return this;
336 }
337
338 /**
339 * Adds each element of {@code elements} to the {@code ImmutableCollection}
340 * being built.
341 *
342 * <p>Note that each builder class overrides this method in order to
343 * covariantly return its own type.
344 *
345 * @param elements the elements to add
346 * @return this {@code Builder} instance
347 * @throws NullPointerException if {@code elements} is null or contains a
348 * null element
349 */
350 public Builder<E> addAll(Iterable<? extends E> elements) {
351 for (E element : elements) {
352 add(element);
353 }
354 return this;
355 }
356
357 /**
358 * Adds each element of {@code elements} to the {@code ImmutableCollection}
359 * being built.
360 *
361 * <p>Note that each builder class overrides this method in order to
362 * covariantly return its own type.
363 *
364 * @param elements the elements to add
365 * @return this {@code Builder} instance
366 * @throws NullPointerException if {@code elements} is null or contains a
367 * null element
368 */
369 public Builder<E> addAll(Iterator<? extends E> elements) {
370 while (elements.hasNext()) {
371 add(elements.next());
372 }
373 return this;
374 }
375
376 /**
377 * Returns a newly-created {@code ImmutableCollection} of the appropriate
378 * type, containing the elements provided to this builder.
379 *
380 * <p>Note that each builder class covariantly returns the appropriate type
381 * of {@code ImmutableCollection} from this method.
382 */
383 public abstract ImmutableCollection<E> build();
384 }
385 }