10888a09821a98ac0680fad765217302858e70fa4Paul Duffin/* 20888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Copyright (C) 2009 The Guava Authors 30888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 40888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 50888a09821a98ac0680fad765217302858e70fa4Paul Duffin * you may not use this file except in compliance with the License. 60888a09821a98ac0680fad765217302858e70fa4Paul Duffin * You may obtain a copy of the License at 70888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 80888a09821a98ac0680fad765217302858e70fa4Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 90888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 100888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Unless required by applicable law or agreed to in writing, software 110888a09821a98ac0680fad765217302858e70fa4Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 120888a09821a98ac0680fad765217302858e70fa4Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130888a09821a98ac0680fad765217302858e70fa4Paul Duffin * See the License for the specific language governing permissions and 140888a09821a98ac0680fad765217302858e70fa4Paul Duffin * limitations under the License. 150888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 160888a09821a98ac0680fad765217302858e70fa4Paul Duffin 170888a09821a98ac0680fad765217302858e70fa4Paul Duffinpackage com.google.common.collect; 180888a09821a98ac0680fad765217302858e70fa4Paul Duffin 190888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.Preconditions.checkNotNull; 200888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.collect.CollectPreconditions.checkEntryNotNull; 210888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.collect.Iterables.getOnlyElement; 220888a09821a98ac0680fad765217302858e70fa4Paul Duffin 230888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.io.Serializable; 240888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Collections; 250888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.EnumMap; 260888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Iterator; 270888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.List; 280888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Map; 290888a09821a98ac0680fad765217302858e70fa4Paul Duffin 300888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport javax.annotation.Nullable; 310888a09821a98ac0680fad765217302858e70fa4Paul Duffin 320888a09821a98ac0680fad765217302858e70fa4Paul Duffin/** 330888a09821a98ac0680fad765217302858e70fa4Paul Duffin * GWT emulation of {@link ImmutableMap}. For non sorted maps, it is a thin 340888a09821a98ac0680fad765217302858e70fa4Paul Duffin * wrapper around {@link java.util.Collections#emptyMap()}, {@link 350888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Collections#singletonMap(Object, Object)} and {@link java.util.LinkedHashMap} 360888a09821a98ac0680fad765217302858e70fa4Paul Duffin * for empty, singleton and regular maps respectively. For sorted maps, it's 370888a09821a98ac0680fad765217302858e70fa4Paul Duffin * a thin wrapper around {@link java.util.TreeMap}. 380888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 390888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @see ImmutableSortedMap 400888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 410888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @author Hayward Chan 420888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 430888a09821a98ac0680fad765217302858e70fa4Paul Duffinpublic abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable { 440888a09821a98ac0680fad765217302858e70fa4Paul Duffin 450888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableMap() {} 460888a09821a98ac0680fad765217302858e70fa4Paul Duffin 470888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ImmutableMap<K, V> of() { 480888a09821a98ac0680fad765217302858e70fa4Paul Duffin return ImmutableBiMap.of(); 490888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 500888a09821a98ac0680fad765217302858e70fa4Paul Duffin 510888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ImmutableMap<K, V> of(K k1, V v1) { 520888a09821a98ac0680fad765217302858e70fa4Paul Duffin return ImmutableBiMap.of(k1, v1); 530888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 540888a09821a98ac0680fad765217302858e70fa4Paul Duffin 550888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ImmutableMap<K, V> of(K k1, V v1, K k2, V v2) { 560888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new RegularImmutableMap<K, V>(entryOf(k1, v1), entryOf(k2, v2)); 570888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 580888a09821a98ac0680fad765217302858e70fa4Paul Duffin 590888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ImmutableMap<K, V> of( 600888a09821a98ac0680fad765217302858e70fa4Paul Duffin K k1, V v1, K k2, V v2, K k3, V v3) { 610888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new RegularImmutableMap<K, V>( 620888a09821a98ac0680fad765217302858e70fa4Paul Duffin entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3)); 630888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 640888a09821a98ac0680fad765217302858e70fa4Paul Duffin 650888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ImmutableMap<K, V> of( 660888a09821a98ac0680fad765217302858e70fa4Paul Duffin K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { 670888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new RegularImmutableMap<K, V>( 680888a09821a98ac0680fad765217302858e70fa4Paul Duffin entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4)); 690888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 700888a09821a98ac0680fad765217302858e70fa4Paul Duffin 710888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ImmutableMap<K, V> of( 720888a09821a98ac0680fad765217302858e70fa4Paul Duffin K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { 730888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new RegularImmutableMap<K, V>(entryOf(k1, v1), 740888a09821a98ac0680fad765217302858e70fa4Paul Duffin entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5)); 750888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 760888a09821a98ac0680fad765217302858e70fa4Paul Duffin 770888a09821a98ac0680fad765217302858e70fa4Paul Duffin // looking for of() with > 5 entries? Use the builder instead. 780888a09821a98ac0680fad765217302858e70fa4Paul Duffin 790888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Builder<K, V> builder() { 800888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new Builder<K, V>(); 810888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 820888a09821a98ac0680fad765217302858e70fa4Paul Duffin 830888a09821a98ac0680fad765217302858e70fa4Paul Duffin static <K, V> Entry<K, V> entryOf(K key, V value) { 840888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkEntryNotNull(key, value); 850888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Maps.immutableEntry(key, value); 860888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 870888a09821a98ac0680fad765217302858e70fa4Paul Duffin 880888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static class Builder<K, V> { 890888a09821a98ac0680fad765217302858e70fa4Paul Duffin final List<Entry<K, V>> entries = Lists.newArrayList(); 900888a09821a98ac0680fad765217302858e70fa4Paul Duffin 910888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Builder() {} 920888a09821a98ac0680fad765217302858e70fa4Paul Duffin 930888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Builder<K, V> put(K key, V value) { 940888a09821a98ac0680fad765217302858e70fa4Paul Duffin entries.add(entryOf(key, value)); 950888a09821a98ac0680fad765217302858e70fa4Paul Duffin return this; 960888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 970888a09821a98ac0680fad765217302858e70fa4Paul Duffin 980888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Builder<K, V> put(Entry<? extends K, ? extends V> entry) { 990888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (entry instanceof ImmutableEntry) { 1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkNotNull(entry.getKey()); 1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkNotNull(entry.getValue()); 1020888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // all supported methods are covariant 1030888a09821a98ac0680fad765217302858e70fa4Paul Duffin Entry<K, V> immutableEntry = (Entry<K, V>) entry; 1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin entries.add(immutableEntry); 1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin } else { 1060888a09821a98ac0680fad765217302858e70fa4Paul Duffin entries.add(entryOf((K) entry.getKey(), (V) entry.getValue())); 1070888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin return this; 1090888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1110888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Builder<K, V> putAll(Map<? extends K, ? extends V> map) { 1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Entry<? extends K, ? extends V> entry : map.entrySet()) { 1130888a09821a98ac0680fad765217302858e70fa4Paul Duffin put(entry.getKey(), entry.getValue()); 1140888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1150888a09821a98ac0680fad765217302858e70fa4Paul Duffin return this; 1160888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1170888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin public ImmutableMap<K, V> build() { 1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin return fromEntryList(entries); 1200888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1210888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1220888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static <K, V> ImmutableMap<K, V> fromEntryList( 1230888a09821a98ac0680fad765217302858e70fa4Paul Duffin List<Entry<K, V>> entries) { 1240888a09821a98ac0680fad765217302858e70fa4Paul Duffin int size = entries.size(); 1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin switch (size) { 1260888a09821a98ac0680fad765217302858e70fa4Paul Duffin case 0: 1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin return of(); 1280888a09821a98ac0680fad765217302858e70fa4Paul Duffin case 1: 1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin Entry<K, V> entry = getOnlyElement(entries); 1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin return of(entry.getKey(), entry.getValue()); 1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin default: 1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") 1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin Entry<K, V>[] entryArray 1340888a09821a98ac0680fad765217302858e70fa4Paul Duffin = entries.toArray(new Entry[entries.size()]); 1350888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new RegularImmutableMap<K, V>(entryArray); 1360888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1380888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1390888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ImmutableMap<K, V> copyOf( 1410888a09821a98ac0680fad765217302858e70fa4Paul Duffin Map<? extends K, ? extends V> map) { 1420888a09821a98ac0680fad765217302858e70fa4Paul Duffin if ((map instanceof ImmutableMap) && !(map instanceof ImmutableSortedMap)) { 1430888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // safe since map is not writable 1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableMap<K, V> kvMap = (ImmutableMap<K, V>) map; 1450888a09821a98ac0680fad765217302858e70fa4Paul Duffin return kvMap; 1460888a09821a98ac0680fad765217302858e70fa4Paul Duffin } else if (map instanceof EnumMap) { 1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin EnumMap<?, ?> enumMap = (EnumMap<?, ?>) map; 1480888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Map.Entry<?, ?> entry : enumMap.entrySet()) { 1490888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkNotNull(entry.getKey()); 1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkNotNull(entry.getValue()); 1510888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1520888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") 1530888a09821a98ac0680fad765217302858e70fa4Paul Duffin // immutable collections are safe for covariant casts 1540888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableMap<K, V> result = ImmutableEnumMap.asImmutable(new EnumMap(enumMap)); 1550888a09821a98ac0680fad765217302858e70fa4Paul Duffin return result; 1560888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1570888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1580888a09821a98ac0680fad765217302858e70fa4Paul Duffin int size = map.size(); 1590888a09821a98ac0680fad765217302858e70fa4Paul Duffin switch (size) { 1600888a09821a98ac0680fad765217302858e70fa4Paul Duffin case 0: 1610888a09821a98ac0680fad765217302858e70fa4Paul Duffin return of(); 1620888a09821a98ac0680fad765217302858e70fa4Paul Duffin case 1: 1630888a09821a98ac0680fad765217302858e70fa4Paul Duffin Entry<? extends K, ? extends V> entry 1640888a09821a98ac0680fad765217302858e70fa4Paul Duffin = getOnlyElement(map.entrySet()); 1650888a09821a98ac0680fad765217302858e70fa4Paul Duffin return ImmutableMap.<K, V>of(entry.getKey(), entry.getValue()); 1660888a09821a98ac0680fad765217302858e70fa4Paul Duffin default: 1670888a09821a98ac0680fad765217302858e70fa4Paul Duffin Map<K, V> orderPreservingCopy = Maps.newLinkedHashMap(); 1680888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Entry<? extends K, ? extends V> e : map.entrySet()) { 1690888a09821a98ac0680fad765217302858e70fa4Paul Duffin orderPreservingCopy.put( 1700888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkNotNull(e.getKey()), checkNotNull(e.getValue())); 1710888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new RegularImmutableMap<K, V>(orderPreservingCopy); 1730888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1740888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1760888a09821a98ac0680fad765217302858e70fa4Paul Duffin abstract boolean isPartialView(); 1770888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin public final V put(K k, V v) { 1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new UnsupportedOperationException(); 1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin public final V remove(Object o) { 1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new UnsupportedOperationException(); 1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin public final void putAll(Map<? extends K, ? extends V> map) { 1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new UnsupportedOperationException(); 1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin public final void clear() { 1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new UnsupportedOperationException(); 1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin public boolean isEmpty() { 1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin return size() == 0; 1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1990888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2000888a09821a98ac0680fad765217302858e70fa4Paul Duffin public boolean containsKey(@Nullable Object key) { 2010888a09821a98ac0680fad765217302858e70fa4Paul Duffin return get(key) != null; 2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2030888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2040888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2050888a09821a98ac0680fad765217302858e70fa4Paul Duffin public boolean containsValue(@Nullable Object value) { 2060888a09821a98ac0680fad765217302858e70fa4Paul Duffin return values().contains(value); 2070888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2080888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2090888a09821a98ac0680fad765217302858e70fa4Paul Duffin private transient ImmutableSet<Entry<K, V>> cachedEntrySet = null; 2100888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2110888a09821a98ac0680fad765217302858e70fa4Paul Duffin public final ImmutableSet<Entry<K, V>> entrySet() { 2120888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (cachedEntrySet != null) { 2130888a09821a98ac0680fad765217302858e70fa4Paul Duffin return cachedEntrySet; 2140888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin return cachedEntrySet = createEntrySet(); 2160888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2170888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2180888a09821a98ac0680fad765217302858e70fa4Paul Duffin abstract ImmutableSet<Entry<K, V>> createEntrySet(); 2190888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2200888a09821a98ac0680fad765217302858e70fa4Paul Duffin private transient ImmutableSet<K> cachedKeySet = null; 2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2220888a09821a98ac0680fad765217302858e70fa4Paul Duffin public ImmutableSet<K> keySet() { 2230888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (cachedKeySet != null) { 2240888a09821a98ac0680fad765217302858e70fa4Paul Duffin return cachedKeySet; 2250888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2260888a09821a98ac0680fad765217302858e70fa4Paul Duffin return cachedKeySet = createKeySet(); 2270888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2280888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2290888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableSet<K> createKeySet() { 2300888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new ImmutableMapKeySet<K, V>(this); 2310888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2320888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2330888a09821a98ac0680fad765217302858e70fa4Paul Duffin private transient ImmutableCollection<V> cachedValues = null; 2340888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2350888a09821a98ac0680fad765217302858e70fa4Paul Duffin public ImmutableCollection<V> values() { 2360888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (cachedValues != null) { 2370888a09821a98ac0680fad765217302858e70fa4Paul Duffin return cachedValues; 2380888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2390888a09821a98ac0680fad765217302858e70fa4Paul Duffin return cachedValues = createValues(); 2400888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2410888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2420888a09821a98ac0680fad765217302858e70fa4Paul Duffin // esnickell is editing here 2430888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2440888a09821a98ac0680fad765217302858e70fa4Paul Duffin // cached so that this.multimapView().inverse() only computes inverse once 2450888a09821a98ac0680fad765217302858e70fa4Paul Duffin private transient ImmutableSetMultimap<K, V> multimapView; 2460888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2470888a09821a98ac0680fad765217302858e70fa4Paul Duffin public ImmutableSetMultimap<K, V> asMultimap() { 2480888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableSetMultimap<K, V> result = multimapView; 2490888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (result == null) ? (multimapView = createMultimapView()) : result; 2500888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2510888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2520888a09821a98ac0680fad765217302858e70fa4Paul Duffin private ImmutableSetMultimap<K, V> createMultimapView() { 2530888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableMap<K, ImmutableSet<V>> map = viewValuesAsImmutableSet(); 2540888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new ImmutableSetMultimap<K, V>(map, map.size(), null); 2550888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2560888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2570888a09821a98ac0680fad765217302858e70fa4Paul Duffin private ImmutableMap<K, ImmutableSet<V>> viewValuesAsImmutableSet() { 2580888a09821a98ac0680fad765217302858e70fa4Paul Duffin final Map<K, V> outer = this; 2590888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new ImmutableMap<K, ImmutableSet<V>>() { 2600888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2610888a09821a98ac0680fad765217302858e70fa4Paul Duffin public int size() { 2620888a09821a98ac0680fad765217302858e70fa4Paul Duffin return outer.size(); 2630888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2640888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2650888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2660888a09821a98ac0680fad765217302858e70fa4Paul Duffin public ImmutableSet<V> get(@Nullable Object key) { 2670888a09821a98ac0680fad765217302858e70fa4Paul Duffin V outerValue = outer.get(key); 2680888a09821a98ac0680fad765217302858e70fa4Paul Duffin return outerValue == null ? null : ImmutableSet.of(outerValue); 2690888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2700888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2710888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableSet<Entry<K, ImmutableSet<V>>> createEntrySet() { 2730888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new ImmutableSet<Entry<K, ImmutableSet<V>>>() { 2740888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2750888a09821a98ac0680fad765217302858e70fa4Paul Duffin public UnmodifiableIterator<Entry<K, ImmutableSet<V>>> iterator() { 2760888a09821a98ac0680fad765217302858e70fa4Paul Duffin final Iterator<Entry<K,V>> outerEntryIterator = outer.entrySet().iterator(); 2770888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new UnmodifiableIterator<Entry<K, ImmutableSet<V>>>() { 2780888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2790888a09821a98ac0680fad765217302858e70fa4Paul Duffin public boolean hasNext() { 2800888a09821a98ac0680fad765217302858e70fa4Paul Duffin return outerEntryIterator.hasNext(); 2810888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2820888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2830888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2840888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Entry<K, ImmutableSet<V>> next() { 2850888a09821a98ac0680fad765217302858e70fa4Paul Duffin final Entry<K, V> outerEntry = outerEntryIterator.next(); 2860888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new AbstractMapEntry<K, ImmutableSet<V>>() { 2870888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2880888a09821a98ac0680fad765217302858e70fa4Paul Duffin public K getKey() { 2890888a09821a98ac0680fad765217302858e70fa4Paul Duffin return outerEntry.getKey(); 2900888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2910888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2920888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2930888a09821a98ac0680fad765217302858e70fa4Paul Duffin public ImmutableSet<V> getValue() { 2940888a09821a98ac0680fad765217302858e70fa4Paul Duffin return ImmutableSet.of(outerEntry.getValue()); 2950888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2960888a09821a98ac0680fad765217302858e70fa4Paul Duffin }; 2970888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2980888a09821a98ac0680fad765217302858e70fa4Paul Duffin }; 2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3000888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3010888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3020888a09821a98ac0680fad765217302858e70fa4Paul Duffin boolean isPartialView() { 3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin return false; 3040888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3050888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3060888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3070888a09821a98ac0680fad765217302858e70fa4Paul Duffin public int size() { 3080888a09821a98ac0680fad765217302858e70fa4Paul Duffin return outer.size(); 3090888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3100888a09821a98ac0680fad765217302858e70fa4Paul Duffin }; 3110888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3120888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3130888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3140888a09821a98ac0680fad765217302858e70fa4Paul Duffin boolean isPartialView() { 3150888a09821a98ac0680fad765217302858e70fa4Paul Duffin return false; 3160888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3170888a09821a98ac0680fad765217302858e70fa4Paul Duffin }; 3180888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3190888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3200888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableCollection<V> createValues() { 3210888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new ImmutableMapValues<K, V>(this); 3220888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3230888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3240888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean equals(@Nullable Object object) { 3250888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Maps.equalsImpl(this, object); 3260888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3270888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3280888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int hashCode() { 3290888a09821a98ac0680fad765217302858e70fa4Paul Duffin // not caching hash code since it could change if map values are mutable 3300888a09821a98ac0680fad765217302858e70fa4Paul Duffin // in a way that modifies their hash codes 3310888a09821a98ac0680fad765217302858e70fa4Paul Duffin return entrySet().hashCode(); 3320888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3330888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3340888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public String toString() { 3350888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Maps.toStringImpl(this); 3360888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3370888a09821a98ac0680fad765217302858e70fa4Paul Duffin} 338