1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2008 The Guava Authors 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 Wilson 21090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Map; 22090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 23090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport javax.annotation.Nullable; 24090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/** 26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Implementation of {@link ImmutableMap} with exactly one entry. 27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Jesse Wilson 29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Kevin Bourrillion 30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(serializable = true, emulated = true) 32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson@SuppressWarnings("serial") // uses writeReplace(), not default serialization 33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonfinal class SingletonImmutableMap<K, V> extends ImmutableMap<K, V> { 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson final transient K singleKey; 36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson final transient V singleValue; 37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private transient Entry<K, V> entry; 39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson SingletonImmutableMap(K singleKey, V singleValue) { 41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson this.singleKey = singleKey; 42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson this.singleValue = singleValue; 43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson SingletonImmutableMap(Entry<K, V> entry) { 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.entry = entry; 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.singleKey = entry.getKey(); 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.singleValue = entry.getValue(); 49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private Entry<K, V> entry() { 52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Entry<K, V> e = entry; 53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return (e == null) 54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ? (entry = Maps.immutableEntry(singleKey, singleValue)) : e; 55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V get(@Nullable Object key) { 58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return singleKey.equals(key) ? singleValue : null; 59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public int size() { 63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return 1; 64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean isEmpty() { 67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(@Nullable Object key) { 71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return singleKey.equals(key); 72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsValue(@Nullable Object value) { 75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return singleValue.equals(value); 76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override boolean isPartialView() { 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private transient ImmutableSet<Entry<K, V>> entrySet; 83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 84090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public ImmutableSet<Entry<K, V>> entrySet() { 85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ImmutableSet<Entry<K, V>> es = entrySet; 86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return (es == null) ? (entrySet = ImmutableSet.of(entry())) : es; 87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private transient ImmutableSet<K> keySet; 90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public ImmutableSet<K> keySet() { 92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ImmutableSet<K> ks = keySet; 93090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return (ks == null) ? (keySet = ImmutableSet.of(singleKey)) : ks; 94090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 95090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 96090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private transient ImmutableCollection<V> values; 97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 98090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public ImmutableCollection<V> values() { 99090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ImmutableCollection<V> v = values; 100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return (v == null) ? (values = new Values<V>(singleValue)) : v; 101090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 102090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @SuppressWarnings("serial") // uses writeReplace(), not default serialization 104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private static class Values<V> extends ImmutableCollection<V> { 105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson final V singleValue; 106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 107090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Values(V singleValue) { 108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson this.singleValue = singleValue; 109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 111090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean contains(Object object) { 112090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return singleValue.equals(object); 113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean isEmpty() { 116090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 117090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 118090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 120090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public int size() { 121090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return 1; 122090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 123090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 124090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public UnmodifiableIterator<V> iterator() { 125090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return Iterators.singletonIterator(singleValue); 126090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override boolean isPartialView() { 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 131090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 132090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 133090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public boolean equals(@Nullable Object object) { 134090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (object == this) { 135090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return true; 136090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 137090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (object instanceof Map) { 138090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Map<?, ?> that = (Map<?, ?>) object; 139090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (that.size() != 1) { 140090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 141090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 142090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Entry<?, ?> entry = that.entrySet().iterator().next(); 143090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return singleKey.equals(entry.getKey()) 144090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson && singleValue.equals(entry.getValue()); 145090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 146090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 147090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 148090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 149090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public int hashCode() { 150090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return singleKey.hashCode() ^ singleValue.hashCode(); 151090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 152090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 153090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public String toString() { 154090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return new StringBuilder() 155090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .append('{') 156090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .append(singleKey.toString()) 157090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .append('=') 158090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .append(singleValue.toString()) 159090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .append('}') 160090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson .toString(); 161090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 162090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 163