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