1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/* 2090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Copyright (C) 2007 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 com.google.common.base.Preconditions; 21090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 22090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Set; 23090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 24090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport javax.annotation.Nullable; 25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/** 27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Implementation of {@link ImmutableSet} with exactly one element. 28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Kevin Bourrillion 30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Nick Kralevich 31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson@GwtCompatible(serializable = true) 33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson@SuppressWarnings("serial") // uses writeReplace(), not default serialization 34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonfinal class SingletonImmutableSet<E> extends ImmutableSet<E> { 35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson final transient E element; 36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson // Non-volatile because: 38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson // - Integer is immutable and thus thread-safe; 39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson // - no problems if one thread overwrites the cachedHashCode from another. 40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private transient Integer cachedHashCode; 41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson SingletonImmutableSet(E element) { 43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson this.element = Preconditions.checkNotNull(element); 44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson SingletonImmutableSet(E element, int hashCode) { 47090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson // Guaranteed to be non-null by the presence of the pre-computed hash code. 48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson this.element = element; 49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson cachedHashCode = hashCode; 50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public int size() { 53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return 1; 54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean isEmpty() { 57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean contains(Object target) { 61090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return element.equals(target); 62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public UnmodifiableIterator<E> iterator() { 65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return Iterators.singletonIterator(element); 66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public Object[] toArray() { 69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return new Object[] { element }; 70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @SuppressWarnings({"unchecked"}) 73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public <T> T[] toArray(T[] array) { 74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (array.length == 0) { 75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson array = ObjectArrays.newArray(array, 1); 76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } else if (array.length > 1) { 77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson array[1] = null; 78090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson // Writes will produce ArrayStoreException when the toArray() doc requires. 80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Object[] objectArray = array; 81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson objectArray[0] = element; 82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return array; 83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 84090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean equals(@Nullable Object object) { 86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (object == this) { 87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return true; 88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (object instanceof Set) { 90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Set<?> that = (Set<?>) object; 91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return that.size() == 1 && element.equals(that.iterator().next()); 92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 93090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 94090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 95090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 96090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public final int hashCode() { 97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Integer code = cachedHashCode; 98090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (code == null) { 99090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return cachedHashCode = element.hashCode(); 100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 101090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return code; 102090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override boolean isHashCodeFast() { 105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 107090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public String toString() { 109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson String elementToString = element.toString(); 110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return new StringBuilder(elementToString.length() + 2) 111090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .append('[') 112090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .append(elementToString) 113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .append(']') 114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .toString(); 115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 116090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 117