1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/* 2090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Copyright (C) 2008 Google Inc. 3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * you may not use this file except in compliance with the License. 6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * You may obtain a copy of the License at 7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * See the License for the specific language governing permissions and 14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * limitations under the License. 15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpackage com.google.common.collect; 18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 19090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport com.google.common.annotations.GwtCompatible; 20090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport static com.google.common.base.Preconditions.checkNotNull; 21090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 22090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.Serializable; 23090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Collection; 24090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Iterator; 25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport javax.annotation.Nullable; 27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/** 29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * An immutable collection. Does not permit null elements. 30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 31bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>In addition to the {@link Collection} methods, this class has an {@link 32bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * #asList()} method, which returns a list view of the collection's elements. 33bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p><b>Note</b>: Although this class is not final, it cannot be subclassed 35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * outside of this package as it has no public or protected constructors. Thus, 36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * instances of this type are guaranteed to be immutable. 37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Jesse Wilson 39bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @since 2010.01.04 <b>stable</b> (imported from Google Collections Library) 40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson@GwtCompatible 42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson@SuppressWarnings("serial") // we're overriding default serialization 43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpublic abstract class ImmutableCollection<E> 44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson implements Collection<E>, Serializable { 45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson static final ImmutableCollection<Object> EMPTY_IMMUTABLE_COLLECTION 46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson = new EmptyImmutableCollection(); 47090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ImmutableCollection() {} 49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Returns an unmodifiable iterator across the elements in this collection. 52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public abstract UnmodifiableIterator<E> iterator(); 54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public Object[] toArray() { 56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Object[] newArray = new Object[size()]; 57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return toArray(newArray); 58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public <T> T[] toArray(T[] other) { 61090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int size = size(); 62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (other.length < size) { 63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson other = ObjectArrays.newArray(other, size); 64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } else if (other.length > size) { 65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson other[size] = null; 66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson // Writes will produce ArrayStoreException when the toArray() doc requires. 69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Object[] otherAsObjectArray = other; 70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int index = 0; 71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson for (E element : this) { 72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson otherAsObjectArray[index++] = element; 73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return other; 75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public boolean contains(@Nullable Object object) { 78090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (object == null) { 79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson for (E element : this) { 82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (element.equals(object)) { 83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return true; 84090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public boolean containsAll(Collection<?> targets) { 90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson for (Object target : targets) { 91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (!contains(target)) { 92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 93090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 94090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 95090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return true; 96090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 98090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public boolean isEmpty() { 99090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return size() == 0; 100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 101090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 102090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public String toString() { 103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson StringBuilder sb = new StringBuilder(size() * 16).append('['); 104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Collections2.standardJoiner.appendTo(sb, this); 105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return sb.append(']').toString(); 106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 107090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 111090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 112090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public final boolean add(E e) { 114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 116090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 117090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 118090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 119090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 120090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 121090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 122090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public final boolean remove(Object object) { 123090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 124090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 125090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 126090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 127090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 128090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 129090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 130090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 131090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public final boolean addAll(Collection<? extends E> newElements) { 132090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 133090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 134090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 135090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 136090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 137090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 138090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 139090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 140090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public final boolean removeAll(Collection<?> oldElements) { 141090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 142090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 143090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 144090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 145090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 146090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 147090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 148090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 149090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public final boolean retainAll(Collection<?> elementsToKeep) { 150090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 151090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 152090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 153090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 154090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 155090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 156090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 157090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 158090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public final void clear() { 159090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 160090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 161090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 162bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // TODO: Restructure code so ImmutableList doesn't contain this variable, 163bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // which it doesn't use. 164bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private transient ImmutableList<E> asList; 165bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 166bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 167bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a list view of the collection. 168bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 169bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @since 2010.01.04 <b>tentative</b> 170bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 171bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public ImmutableList<E> asList() { 172bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ImmutableList<E> list = asList; 173bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return (list == null) ? (asList = createAsList()) : list; 174bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 175bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 176bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ImmutableList<E> createAsList() { 177bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor switch (size()) { 178bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor case 0: 179bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return ImmutableList.of(); 180bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor case 1: 181bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return ImmutableList.of(iterator().next()); 182bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor default: 183bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new ImmutableAsList<E>(toArray(), this); 184bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 185bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 186bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 187090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private static class EmptyImmutableCollection 188090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson extends ImmutableCollection<Object> { 189090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public int size() { 190090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return 0; 191090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 192090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 193090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean isEmpty() { 194090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return true; 195090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 196090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 197090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean contains(@Nullable Object object) { 198090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 199090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 200090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 201090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public UnmodifiableIterator<Object> iterator() { 202090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return Iterators.EMPTY_ITERATOR; 203090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 204090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 205090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private static final Object[] EMPTY_ARRAY = new Object[0]; 206090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 207090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public Object[] toArray() { 208090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return EMPTY_ARRAY; 209090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 210090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 211090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public <T> T[] toArray(T[] array) { 212090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (array.length > 0) { 213090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson array[0] = null; 214090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 215090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return array; 216090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 217090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 218090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 219090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private static class ArrayImmutableCollection<E> 220090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson extends ImmutableCollection<E> { 221090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private final E[] elements; 222090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 223090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ArrayImmutableCollection(E[] elements) { 224090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson this.elements = elements; 225090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 226090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 227090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public int size() { 228090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return elements.length; 229090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 230090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 231090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean isEmpty() { 232090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 233090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 234090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 235090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public UnmodifiableIterator<E> iterator() { 236090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return Iterators.forArray(elements); 237090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 238090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 239090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 240090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /* 241090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Serializes ImmutableCollections as their logical contents. This ensures 242090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * that implementation types do not leak into the serialized representation. 243090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 244090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private static class SerializedForm implements Serializable { 245090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson final Object[] elements; 246090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson SerializedForm(Object[] elements) { 247090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson this.elements = elements; 248090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 249090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Object readResolve() { 250090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return elements.length == 0 251090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ? EMPTY_IMMUTABLE_COLLECTION 252090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson : new ArrayImmutableCollection<Object>(Platform.clone(elements)); 253090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 254090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private static final long serialVersionUID = 0; 255090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 256090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 257090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Object writeReplace() { 258090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return new SerializedForm(toArray()); 259090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 260090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 261090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 262090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Abstract base class for builders of {@link ImmutableCollection} types. 263090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 264090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson abstract static class Builder<E> { 265090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 266090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds {@code element} to the {@code ImmutableCollection} being built. 267090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 268090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Note that each builder class covariantly returns its own type from 269090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * this method. 270090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 271090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param element the element to add 272090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} instance 273090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code element} is null 274090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 275090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public abstract Builder<E> add(E element); 276090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 277090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 278090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds each element of {@code elements} to the {@code ImmutableCollection} 279090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * being built. 280090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 281090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Note that each builder class overrides this method in order to 282090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * covariantly return its own type. 283090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 284090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param elements the elements to add 285090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} instance 286090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code elements} is null or contains a 287090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * null element 288090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 289090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public Builder<E> add(E... elements) { 290090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson checkNotNull(elements); // for GWT 291090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson for (E element : elements) { 292090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson add(element); 293090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 294090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return this; 295090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 296090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 297090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 298090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds each element of {@code elements} to the {@code ImmutableCollection} 299090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * being built. 300090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 301090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Note that each builder class overrides this method in order to 302090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * covariantly return its own type. 303090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 304090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param elements the elements to add 305090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} instance 306090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code elements} is null or contains a 307090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * null element 308090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 309090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public Builder<E> addAll(Iterable<? extends E> elements) { 310090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson checkNotNull(elements); // for GWT 311090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson for (E element : elements) { 312090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson add(element); 313090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 314090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return this; 315090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 316090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 317090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 318090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds each element of {@code elements} to the {@code ImmutableCollection} 319090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * being built. 320090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 321090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Note that each builder class overrides this method in order to 322090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * covariantly return its own type. 323090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 324090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param elements the elements to add 325090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} instance 326090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code elements} is null or contains a 327090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * null element 328090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 329090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public Builder<E> addAll(Iterator<? extends E> elements) { 330090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson checkNotNull(elements); // for GWT 331090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson while (elements.hasNext()) { 332090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson add(elements.next()); 333090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 334090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return this; 335090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 336090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 337090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 338090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Returns a newly-created {@code ImmutableCollection} of the appropriate 339090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * type, containing the elements provided to this builder. 340090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 341090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Note that each builder class covariantly returns the appropriate type 342090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * of {@code ImmutableCollection} from this method. 343090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 344090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public abstract ImmutableCollection<E> build(); 345090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 346090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 347