javadoc.src-html.com.google.common.collect.ImmutableSet.html Maven / Gradle / Ivy
The newest version!
001 /*
002 * Copyright (C) 2007 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 static com.google.common.base.Preconditions.checkArgument;
020 import static com.google.common.base.Preconditions.checkNotNull;
021
022 import com.google.common.annotations.GwtCompatible;
023 import com.google.common.primitives.Ints;
024
025 import java.io.Serializable;
026 import java.util.ArrayList;
027 import java.util.Collection;
028 import java.util.Collections;
029 import java.util.HashSet;
030 import java.util.Iterator;
031 import java.util.Set;
032
033 import javax.annotation.Nullable;
034
035 /**
036 * A high-performance, immutable {@code Set} with reliable, user-specified
037 * iteration order. Does not permit null elements.
038 *
039 * <p>Unlike {@link Collections#unmodifiableSet}, which is a <i>view</i> of a
040 * separate collection that can still change, an instance of this class contains
041 * its own private data and will <i>never</i> change. This class is convenient
042 * for {@code public static final} sets ("constant sets") and also lets you
043 * easily make a "defensive copy" of a set provided to your class by a caller.
044 *
045 * <p><b>Warning:</b> Like most sets, an {@code ImmutableSet} will not function
046 * correctly if an element is modified after being placed in the set. For this
047 * reason, and to avoid general confusion, it is strongly recommended to place
048 * only immutable objects into this collection.
049 *
050 * <p>This class has been observed to perform significantly better than {@link
051 * HashSet} for objects with very fast {@link Object#hashCode} implementations
052 * (as a well-behaved immutable object should). While this class's factory
053 * methods create hash-based instances, the {@link ImmutableSortedSet} subclass
054 * performs binary searches instead.
055 *
056 * <p><b>Note:</b> Although this class is not final, it cannot be subclassed
057 * outside its package as it has no public or protected constructors. Thus,
058 * instances of this type are guaranteed to be immutable.
059 *
060 * @see ImmutableList
061 * @see ImmutableMap
062 * @author Kevin Bourrillion
063 * @author Nick Kralevich
064 * @since 2.0 (imported from Google Collections Library)
065 */
066 @GwtCompatible(serializable = true, emulated = true)
067 @SuppressWarnings("serial") // we're overriding default serialization
068 public abstract class ImmutableSet<E> extends ImmutableCollection<E>
069 implements Set<E> {
070 /**
071 * Returns the empty immutable set. This set behaves and performs comparably
072 * to {@link Collections#emptySet}, and is preferable mainly for consistency
073 * and maintainability of your code.
074 */
075 // Casting to any type is safe because the set will never hold any elements.
076 @SuppressWarnings({"unchecked"})
077 public static <E> ImmutableSet<E> of() {
078 return (ImmutableSet<E>) EmptyImmutableSet.INSTANCE;
079 }
080
081 /**
082 * Returns an immutable set containing a single element. This set behaves and
083 * performs comparably to {@link Collections#singleton}, but will not accept
084 * a null element. It is preferable mainly for consistency and
085 * maintainability of your code.
086 */
087 public static <E> ImmutableSet<E> of(E element) {
088 return new SingletonImmutableSet<E>(element);
089 }
090
091 /**
092 * Returns an immutable set containing the given elements, in order. Repeated
093 * occurrences of an element (according to {@link Object#equals}) after the
094 * first are ignored.
095 *
096 * @throws NullPointerException if any element is null
097 */
098 public static <E> ImmutableSet<E> of(E e1, E e2) {
099 return construct(e1, e2);
100 }
101
102 /**
103 * Returns an immutable set containing the given elements, in order. Repeated
104 * occurrences of an element (according to {@link Object#equals}) after the
105 * first are ignored.
106 *
107 * @throws NullPointerException if any element is null
108 */
109 public static <E> ImmutableSet<E> of(E e1, E e2, E e3) {
110 return construct(e1, e2, e3);
111 }
112
113 /**
114 * Returns an immutable set containing the given elements, in order. Repeated
115 * occurrences of an element (according to {@link Object#equals}) after the
116 * first are ignored.
117 *
118 * @throws NullPointerException if any element is null
119 */
120 public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4) {
121 return construct(e1, e2, e3, e4);
122 }
123
124 /**
125 * Returns an immutable set containing the given elements, in order. Repeated
126 * occurrences of an element (according to {@link Object#equals}) after the
127 * first are ignored.
128 *
129 * @throws NullPointerException if any element is null
130 */
131 public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5) {
132 return construct(e1, e2, e3, e4, e5);
133 }
134
135 /**
136 * Returns an immutable set containing the given elements, in order. Repeated
137 * occurrences of an element (according to {@link Object#equals}) after the
138 * first are ignored.
139 *
140 * @throws NullPointerException if any element is null
141 * @since 3.0 (source-compatible since 2.0)
142 */
143 public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6,
144 E... others) {
145 final int paramCount = 6;
146 Object[] elements = new Object[paramCount + others.length];
147 elements[0] = e1;
148 elements[1] = e2;
149 elements[2] = e3;
150 elements[3] = e4;
151 elements[4] = e5;
152 elements[5] = e6;
153 for (int i = paramCount; i < elements.length; i++) {
154 elements[i] = others[i - paramCount];
155 }
156 return construct(elements);
157 }
158
159 /** {@code elements} has to be internally created array. */
160 private static <E> ImmutableSet<E> construct(Object... elements) {
161 int tableSize = chooseTableSize(elements.length);
162 Object[] table = new Object[tableSize];
163 int mask = tableSize - 1;
164 ArrayList<Object> uniqueElementsList = null;
165 int hashCode = 0;
166 for (int i = 0; i < elements.length; i++) {
167 Object element = elements[i];
168 int hash = element.hashCode();
169 for (int j = Hashing.smear(hash); ; j++) {
170 int index = j & mask;
171 Object value = table[index];
172 if (value == null) {
173 if (uniqueElementsList != null) {
174 uniqueElementsList.add(element);
175 }
176 // Came to an empty slot. Put the element here.
177 table[index] = element;
178 hashCode += hash;
179 break;
180 } else if (value.equals(element)) {
181 if (uniqueElementsList == null) {
182 // first dup
183 uniqueElementsList = new ArrayList<Object>(elements.length);
184 for (int k = 0; k < i; k++) {
185 Object previous = elements[k];
186 uniqueElementsList.add(previous);
187 }
188 }
189 break;
190 }
191 }
192 }
193 Object[] uniqueElements = uniqueElementsList == null
194 ? elements
195 : uniqueElementsList.toArray();
196 if (uniqueElements.length == 1) {
197 // There is only one element or elements are all duplicates
198 @SuppressWarnings("unchecked") // we are careful to only pass in E
199 E element = (E) uniqueElements[0];
200 return new SingletonImmutableSet<E>(element, hashCode);
201 } else if (tableSize > 2 * chooseTableSize(uniqueElements.length)) {
202 // Resize the table when the array includes too many duplicates.
203 // when this happens, we have already made a copy
204 return construct(uniqueElements);
205 } else {
206 return new RegularImmutableSet<E>(uniqueElements, hashCode, table, mask);
207 }
208 }
209
210 // We use power-of-2 tables, and this is the highest int that's a power of 2
211 static final int MAX_TABLE_SIZE = Ints.MAX_POWER_OF_TWO;
212
213 // If the set has this many elements, it will "max out" the table size
214 static final int CUTOFF = 1 << 29;
215
216 /**
217 * Returns an array size suitable for the backing array of a hash table that
218 * uses linear probing in its implementation. The returned size is the
219 * smallest power of two that can hold setSize elements while being at most
220 * 50% full, if possible.
221 */
222 static int chooseTableSize(int setSize) {
223 if (setSize < CUTOFF) {
224 return Integer.highestOneBit(setSize) << 2;
225 }
226
227 // The table can't be completely full or we'll get infinite reprobes
228 checkArgument(setSize < MAX_TABLE_SIZE, "collection too large");
229 return MAX_TABLE_SIZE;
230 }
231
232 /**
233 * Returns an immutable set containing the given elements, in order. Repeated
234 * occurrences of an element (according to {@link Object#equals}) after the
235 * first are ignored.
236 *
237 * @throws NullPointerException if any of {@code elements} is null
238 * @since 3.0
239 */
240 public static <E> ImmutableSet<E> copyOf(E[] elements) {
241 // TODO(benyu): could we delegate to
242 // copyFromCollection(Arrays.asList(elements))?
243 switch (elements.length) {
244 case 0:
245 return of();
246 case 1:
247 return of(elements[0]);
248 default:
249 return construct(elements.clone());
250 }
251 }
252
253 /**
254 * Returns an immutable set containing the given elements, in order. Repeated
255 * occurrences of an element (according to {@link Object#equals}) after the
256 * first are ignored. This method iterates over {@code elements} at most once.
257 *
258 * <p>Note that if {@code s} is a {@code Set<String>}, then {@code
259 * ImmutableSet.copyOf(s)} returns an {@code ImmutableSet<String>} containing
260 * each of the strings in {@code s}, while {@code ImmutableSet.of(s)} returns
261 * a {@code ImmutableSet<Set<String>>} containing one element (the given set
262 * itself).
263 *
264 * <p>Despite the method name, this method attempts to avoid actually copying
265 * the data when it is safe to do so. The exact circumstances under which a
266 * copy will or will not be performed are undocumented and subject to change.
267 *
268 * @throws NullPointerException if any of {@code elements} is null
269 */
270 public static <E> ImmutableSet<E> copyOf(Iterable<? extends E> elements) {
271 return (elements instanceof Collection)
272 ? copyOf(Collections2.cast(elements))
273 : copyOf(elements.iterator());
274 }
275
276 /**
277 * Returns an immutable set containing the given elements, in order. Repeated
278 * occurrences of an element (according to {@link Object#equals}) after the
279 * first are ignored.
280 *
281 * @throws NullPointerException if any of {@code elements} is null
282 */
283 public static <E> ImmutableSet<E> copyOf(Iterator<? extends E> elements) {
284 // TODO(benyu): here we could avoid toArray() for 0 or 1-element list,
285 // worth it?
286 return copyFromCollection(Lists.newArrayList(elements));
287 }
288
289 /**
290 * Returns an immutable set containing the given elements, in order. Repeated
291 * occurrences of an element (according to {@link Object#equals}) after the
292 * first are ignored. This method iterates over {@code elements} at most
293 * once.
294 *
295 * <p>Note that if {@code s} is a {@code Set<String>}, then {@code
296 * ImmutableSet.copyOf(s)} returns an {@code ImmutableSet<String>} containing
297 * each of the strings in {@code s}, while {@code ImmutableSet.of(s)} returns
298 * a {@code ImmutableSet<Set<String>>} containing one element (the given set
299 * itself).
300 *
301 * <p><b>Note:</b> Despite what the method name suggests, {@code copyOf} will
302 * return constant-space views, rather than linear-space copies, of some
303 * inputs known to be immutable. For some other immutable inputs, such as key
304 * sets of an {@code ImmutableMap}, it still performs a copy in order to avoid
305 * holding references to the values of the map. The heuristics used in this
306 * decision are undocumented and subject to change except that:
307 * <ul>
308 * <li>A full copy will be done of any {@code ImmutableSortedSet}.</li>
309 * <li>{@code ImmutableSet.copyOf()} is idempotent with respect to pointer
310 * equality.</li>
311 * </ul>
312 *
313 * <p>This method is safe to use even when {@code elements} is a synchronized
314 * or concurrent collection that is currently being modified by another
315 * thread.
316 *
317 * @throws NullPointerException if any of {@code elements} is null
318 * @since 7.0 (source-compatible since 2.0)
319 */
320 public static <E> ImmutableSet<E> copyOf(Collection<? extends E> elements) {
321 if (elements instanceof ImmutableSet
322 && !(elements instanceof ImmutableSortedSet)) {
323 @SuppressWarnings("unchecked") // all supported methods are covariant
324 ImmutableSet<E> set = (ImmutableSet<E>) elements;
325 if (!set.isPartialView()) {
326 return set;
327 }
328 }
329 return copyFromCollection(elements);
330 }
331
332 private static <E> ImmutableSet<E> copyFromCollection(
333 Collection<? extends E> collection) {
334 Object[] elements = collection.toArray();
335 switch (elements.length) {
336 case 0:
337 return of();
338 case 1:
339 @SuppressWarnings("unchecked") // collection had only Es in it
340 E onlyElement = (E) elements[0];
341 return of(onlyElement);
342 default:
343 // safe to use the array without copying it
344 // as specified by Collection.toArray().
345 return construct(elements);
346 }
347 }
348
349 ImmutableSet() {}
350
351 /** Returns {@code true} if the {@code hashCode()} method runs quickly. */
352 boolean isHashCodeFast() {
353 return false;
354 }
355
356 @Override public boolean equals(@Nullable Object object) {
357 if (object == this) {
358 return true;
359 }
360 if (object instanceof ImmutableSet
361 && isHashCodeFast()
362 && ((ImmutableSet<?>) object).isHashCodeFast()
363 && hashCode() != object.hashCode()) {
364 return false;
365 }
366 return Sets.equalsImpl(this, object);
367 }
368
369 @Override public int hashCode() {
370 return Sets.hashCodeImpl(this);
371 }
372
373 // This declaration is needed to make Set.iterator() and
374 // ImmutableCollection.iterator() consistent.
375 @Override public abstract UnmodifiableIterator<E> iterator();
376
377 abstract static class ArrayImmutableSet<E> extends ImmutableSet<E> {
378 // the elements (two or more) in the desired order.
379 final transient Object[] elements;
380
381 ArrayImmutableSet(Object[] elements) {
382 this.elements = elements;
383 }
384
385 @Override
386 public int size() {
387 return elements.length;
388 }
389
390 @Override public boolean isEmpty() {
391 return false;
392 }
393
394 /*
395 * The cast is safe because the only way to create an instance is via the
396 * create() method above, which only permits elements of type E.
397 */
398 @SuppressWarnings("unchecked")
399 @Override public UnmodifiableIterator<E> iterator() {
400 return (UnmodifiableIterator<E>) Iterators.forArray(elements);
401 }
402
403 @Override public Object[] toArray() {
404 Object[] array = new Object[size()];
405 System.arraycopy(elements, 0, array, 0, size());
406 return array;
407 }
408
409 @Override public <T> T[] toArray(T[] array) {
410 int size = size();
411 if (array.length < size) {
412 array = ObjectArrays.newArray(array, size);
413 } else if (array.length > size) {
414 array[size] = null;
415 }
416 System.arraycopy(elements, 0, array, 0, size);
417 return array;
418 }
419
420 @Override public boolean containsAll(Collection<?> targets) {
421 if (targets == this) {
422 return true;
423 }
424 if (!(targets instanceof ArrayImmutableSet)) {
425 return super.containsAll(targets);
426 }
427 if (targets.size() > size()) {
428 return false;
429 }
430 for (Object target : ((ArrayImmutableSet<?>) targets).elements) {
431 if (!contains(target)) {
432 return false;
433 }
434 }
435 return true;
436 }
437
438 @Override boolean isPartialView() {
439 return false;
440 }
441
442 @Override ImmutableList<E> createAsList() {
443 return new ImmutableAsList<E>(elements, this);
444 }
445 }
446
447 /** such as ImmutableMap.keySet() */
448 abstract static class TransformedImmutableSet<D, E> extends ImmutableSet<E> {
449 final D[] source;
450 final int hashCode;
451
452 TransformedImmutableSet(D[] source, int hashCode) {
453 this.source = source;
454 this.hashCode = hashCode;
455 }
456
457 abstract E transform(D element);
458
459 @Override
460 public int size() {
461 return source.length;
462 }
463
464 @Override public boolean isEmpty() {
465 return false;
466 }
467
468 @Override public UnmodifiableIterator<E> iterator() {
469 return new AbstractIndexedListIterator<E>(source.length) {
470 @Override protected E get(int index) {
471 return transform(source[index]);
472 }
473 };
474 }
475
476 @Override public Object[] toArray() {
477 return toArray(new Object[size()]);
478 }
479
480 @Override public <T> T[] toArray(T[] array) {
481 int size = size();
482 if (array.length < size) {
483 array = ObjectArrays.newArray(array, size);
484 } else if (array.length > size) {
485 array[size] = null;
486 }
487
488 // Writes will produce ArrayStoreException when the toArray() doc requires
489 Object[] objectArray = array;
490 for (int i = 0; i < source.length; i++) {
491 objectArray[i] = transform(source[i]);
492 }
493 return array;
494 }
495
496 @Override public final int hashCode() {
497 return hashCode;
498 }
499
500 @Override boolean isHashCodeFast() {
501 return true;
502 }
503 }
504
505 /*
506 * This class is used to serialize all ImmutableSet instances, except for
507 * ImmutableEnumSet/ImmutableSortedSet, regardless of implementation type. It
508 * captures their "logical contents" and they are reconstructed using public
509 * static factories. This is necessary to ensure that the existence of a
510 * particular implementation type is an implementation detail.
511 */
512 private static class SerializedForm implements Serializable {
513 final Object[] elements;
514 SerializedForm(Object[] elements) {
515 this.elements = elements;
516 }
517 Object readResolve() {
518 return copyOf(elements);
519 }
520 private static final long serialVersionUID = 0;
521 }
522
523 @Override Object writeReplace() {
524 return new SerializedForm(toArray());
525 }
526
527 /**
528 * Returns a new builder. The generated builder is equivalent to the builder
529 * created by the {@link Builder} constructor.
530 */
531 public static <E> Builder<E> builder() {
532 return new Builder<E>();
533 }
534
535 /**
536 * A builder for creating immutable set instances, especially {@code public
537 * static final} sets ("constant sets"). Example: <pre> {@code
538 *
539 * public static final ImmutableSet<Color> GOOGLE_COLORS =
540 * new ImmutableSet.Builder<Color>()
541 * .addAll(WEBSAFE_COLORS)
542 * .add(new Color(0, 191, 255))
543 * .build();}</pre>
544 *
545 * Builder instances can be reused; it is safe to call {@link #build} multiple
546 * times to build multiple sets in series. Each set is a superset of the set
547 * created before it.
548 *
549 * @since 2.0 (imported from Google Collections Library)
550 */
551 public static class Builder<E> extends ImmutableCollection.Builder<E> {
552 // accessed directly by ImmutableSortedSet
553 final ArrayList<E> contents = Lists.newArrayList();
554
555 /**
556 * Creates a new builder. The returned builder is equivalent to the builder
557 * generated by {@link ImmutableSet#builder}.
558 */
559 public Builder() {}
560
561 /**
562 * Adds {@code element} to the {@code ImmutableSet}. If the {@code
563 * ImmutableSet} already contains {@code element}, then {@code add} has no
564 * effect (only the previously added element is retained).
565 *
566 * @param element the element to add
567 * @return this {@code Builder} object
568 * @throws NullPointerException if {@code element} is null
569 */
570 @Override public Builder<E> add(E element) {
571 contents.add(checkNotNull(element));
572 return this;
573 }
574
575 /**
576 * Adds each element of {@code elements} to the {@code ImmutableSet},
577 * ignoring duplicate elements (only the first duplicate element is added).
578 *
579 * @param elements the elements to add
580 * @return this {@code Builder} object
581 * @throws NullPointerException if {@code elements} is null or contains a
582 * null element
583 */
584 @Override public Builder<E> add(E... elements) {
585 contents.ensureCapacity(contents.size() + elements.length);
586 super.add(elements);
587 return this;
588 }
589
590 /**
591 * Adds each element of {@code elements} to the {@code ImmutableSet},
592 * ignoring duplicate elements (only the first duplicate element is added).
593 *
594 * @param elements the {@code Iterable} to add to the {@code ImmutableSet}
595 * @return this {@code Builder} object
596 * @throws NullPointerException if {@code elements} is null or contains a
597 * null element
598 */
599 @Override public Builder<E> addAll(Iterable<? extends E> elements) {
600 if (elements instanceof Collection) {
601 Collection<?> collection = (Collection<?>) elements;
602 contents.ensureCapacity(contents.size() + collection.size());
603 }
604 super.addAll(elements);
605 return this;
606 }
607
608 /**
609 * Adds each element of {@code elements} to the {@code ImmutableSet},
610 * ignoring duplicate elements (only the first duplicate element is added).
611 *
612 * @param elements the elements to add to the {@code ImmutableSet}
613 * @return this {@code Builder} object
614 * @throws NullPointerException if {@code elements} is null or contains a
615 * null element
616 */
617 @Override public Builder<E> addAll(Iterator<? extends E> elements) {
618 super.addAll(elements);
619 return this;
620 }
621
622 /**
623 * Returns a newly-created {@code ImmutableSet} based on the contents of
624 * the {@code Builder}.
625 */
626 @Override public ImmutableSet<E> build() {
627 return copyOf(contents);
628 }
629 }
630 }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy