Maps.java revision 7dd252788645e940eada959bdde927426e2531c9
11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Equivalence; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Joiner.MapJoiner; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Objects; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Preconditions; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicate; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicates; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.MapDifference.ValueDifference; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.primitives.Ints; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractCollection; 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractMap; 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection; 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections; 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator; 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.EnumMap; 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Enumeration; 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.HashMap; 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.IdentityHashMap; 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator; 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.LinkedHashMap; 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry; 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Properties; 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set; 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedMap; 527dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.SortedSet; 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.TreeMap; 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ConcurrentMap; 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 597dd252788645e940eada959bdde927426e2531c9Paul Duffin * Static utility methods pertaining to {@link Map} instances (including instances of 607dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@link SortedMap}, {@link BiMap}, etc.). Also see this class's counterparts 617dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@link Lists}, {@link Sets} and {@link Queues}. 627dd252788645e940eada959bdde927426e2531c9Paul Duffin * 637dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>See the Guava User Guide article on <a href= 647dd252788645e940eada959bdde927426e2531c9Paul Duffin * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Maps"> 657dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code Maps}</a>. 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kevin Bourrillion 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Isaac Shum 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library) 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true) 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class Maps { 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Maps() {} 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 777dd252788645e940eada959bdde927426e2531c9Paul Duffin private enum EntryFunction implements Function<Entry, Object> { 787dd252788645e940eada959bdde927426e2531c9Paul Duffin KEY { 797dd252788645e940eada959bdde927426e2531c9Paul Duffin 807dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 817dd252788645e940eada959bdde927426e2531c9Paul Duffin public Object apply(Entry entry) { 827dd252788645e940eada959bdde927426e2531c9Paul Duffin return entry.getKey(); 837dd252788645e940eada959bdde927426e2531c9Paul Duffin } 847dd252788645e940eada959bdde927426e2531c9Paul Duffin }, 857dd252788645e940eada959bdde927426e2531c9Paul Duffin VALUE { 867dd252788645e940eada959bdde927426e2531c9Paul Duffin 877dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 887dd252788645e940eada959bdde927426e2531c9Paul Duffin public Object apply(Entry entry) { 897dd252788645e940eada959bdde927426e2531c9Paul Duffin return entry.getValue(); 907dd252788645e940eada959bdde927426e2531c9Paul Duffin } 917dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 927dd252788645e940eada959bdde927426e2531c9Paul Duffin } 937dd252788645e940eada959bdde927426e2531c9Paul Duffin 947dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unchecked") 957dd252788645e940eada959bdde927426e2531c9Paul Duffin static <K> Function<Entry<K, ?>, K> keyFunction() { 967dd252788645e940eada959bdde927426e2531c9Paul Duffin return (Function) EntryFunction.KEY; 977dd252788645e940eada959bdde927426e2531c9Paul Duffin } 987dd252788645e940eada959bdde927426e2531c9Paul Duffin 997dd252788645e940eada959bdde927426e2531c9Paul Duffin static <V> Function<Entry<?, V>, V> valueFunction() { 1007dd252788645e940eada959bdde927426e2531c9Paul Duffin return (Function) EntryFunction.VALUE; 1017dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1027dd252788645e940eada959bdde927426e2531c9Paul Duffin 1037dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 1047dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns an immutable map instance containing the given entries. 1057dd252788645e940eada959bdde927426e2531c9Paul Duffin * Internally, the returned set will be backed by an {@link EnumMap}. 1067dd252788645e940eada959bdde927426e2531c9Paul Duffin * 1077dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>The iteration order of the returned map follows the enum's iteration 1087dd252788645e940eada959bdde927426e2531c9Paul Duffin * order, not the order in which the elements appear in the given map. 1097dd252788645e940eada959bdde927426e2531c9Paul Duffin * 1107dd252788645e940eada959bdde927426e2531c9Paul Duffin * @param map the map to make an immutable copy of 1117dd252788645e940eada959bdde927426e2531c9Paul Duffin * @return an immutable map containing those entries 1127dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 14.0 1137dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 1147dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtCompatible(serializable = true) 1157dd252788645e940eada959bdde927426e2531c9Paul Duffin @Beta 1167dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K extends Enum<K>, V> ImmutableMap<K, V> immutableEnumMap(Map<K, V> map) { 1177dd252788645e940eada959bdde927426e2531c9Paul Duffin if (map instanceof ImmutableEnumMap) { 1187dd252788645e940eada959bdde927426e2531c9Paul Duffin return (ImmutableEnumMap<K, V>) map; 1197dd252788645e940eada959bdde927426e2531c9Paul Duffin } else if (map.isEmpty()) { 1207dd252788645e940eada959bdde927426e2531c9Paul Duffin return ImmutableMap.of(); 1217dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 1227dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Map.Entry<K, V> entry : map.entrySet()) { 1237dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(entry.getKey()); 1247dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(entry.getValue()); 1257dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1267dd252788645e940eada959bdde927426e2531c9Paul Duffin return ImmutableEnumMap.asImmutable(new EnumMap<K, V>(map)); 1277dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1287dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1297dd252788645e940eada959bdde927426e2531c9Paul Duffin 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, empty {@code HashMap} instance. 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMap#of()} instead. 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #newEnumMap} instead. 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code HashMap} 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> HashMap<K, V> newHashMap() { 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new HashMap<K, V>(); 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a {@code HashMap} instance, with a high enough "initial capacity" 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that it <i>should</i> hold {@code expectedSize} elements without growth. 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * This behavior cannot be broadly guaranteed, but it is observed to be true 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for OpenJDK 1.6. It also can't be guaranteed that the method isn't 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inadvertently <i>oversizing</i> the returned map. 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param expectedSize the number of elements you expect to add to the 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned map 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code HashMap} with enough capacity to hold {@code 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * expectedSize} elements without resizing 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code expectedSize} is negative 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1587dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize) { 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new HashMap<K, V>(capacity(expectedSize)); 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a capacity that is sufficient to keep the map from being resized as 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * long as it grows no larger than expectedSize and the load factor is >= its 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * default (0.75). 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static int capacity(int expectedSize) { 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (expectedSize < 3) { 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(expectedSize >= 0); 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return expectedSize + 1; 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (expectedSize < Ints.MAX_POWER_OF_TWO) { 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return expectedSize + expectedSize / 3; 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Integer.MAX_VALUE; // any large value 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i> {@code HashMap} instance with the same mappings as 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the specified map. 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMap#copyOf(Map)} instead. 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if {@code K} is an {@link Enum} type, use {@link 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #newEnumMap} instead. 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the mappings to be placed in the new map 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new {@code HashMap} initialized with the mappings from {@code 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map} 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1927dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> HashMap<K, V> newHashMap(Map<? extends K, ? extends V> map) { 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new HashMap<K, V>(map); 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, empty, insertion-ordered {@code LinkedHashMap} 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * instance. 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMap#of()} instead. 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code LinkedHashMap} 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() { 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new LinkedHashMap<K, V>(); 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, insertion-ordered {@code LinkedHashMap} instance 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * with the same mappings as the specified map. 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMap#copyOf(Map)} instead. 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the mappings to be placed in the new map 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, {@code LinkedHashMap} initialized with the mappings from 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code map} 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2207dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> map) { 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new LinkedHashMap<K, V>(map); 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a general-purpose instance of {@code ConcurrentMap}, which supports 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * all optional operations of the ConcurrentMap interface. It does not permit 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null keys or values. It is serializable. 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This is currently accomplished by calling {@link MapMaker#makeMap()}. 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It is preferable to use {@code MapMaker} directly (rather than through 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this method), as it presents numerous useful configuration options, 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * such as the concurrency level, load factor, key/value reference types, 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and value computation. 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code ConcurrentMap} 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 3.0 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ConcurrentMap<K, V> newConcurrentMap() { 2407dd252788645e940eada959bdde927426e2531c9Paul Duffin return new MapMaker().<K, V> makeMap(); 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the natural 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ordering of its elements. 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSortedMap#of()} instead. 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code TreeMap} 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() { 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TreeMap<K, V>(); 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i> {@code TreeMap} instance with the same mappings as 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the specified map and using the same ordering as the specified map. 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSortedMap#copyOfSorted(SortedMap)} instead. 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the sorted map whose mappings are to be placed in the new map 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and whose comparator is to be used to sort the new map 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new {@code TreeMap} initialized with the mappings from {@code 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map} and using the comparator of {@code map} 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> TreeMap<K, V> newTreeMap(SortedMap<K, ? extends V> map) { 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TreeMap<K, V>(map); 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the given 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * comparator. 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@code 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSortedMap.orderedBy(comparator).build()} instead. 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param comparator the comparator to sort the keys with 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code TreeMap} 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2827dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <C, K extends C, V> TreeMap<K, V> newTreeMap(@Nullable Comparator<C> comparator) { 2837dd252788645e940eada959bdde927426e2531c9Paul Duffin // Ideally, the extra type parameter "C" shouldn't be necessary. It is a 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // work-around of a compiler type inference quirk that prevents the 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // following code from being compiled: 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Comparator<Class<?>> comparator = null; 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Map<Class<? extends Throwable>, String> map = newTreeMap(comparator); 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TreeMap<K, V>(comparator); 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an {@code EnumMap} instance. 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param type the key type for this map 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code EnumMap} 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Class<K> type) { 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EnumMap<K, V>(checkNotNull(type)); 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an {@code EnumMap} with the same mappings as the specified map. 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the map from which to initialize this {@code EnumMap} 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new {@code EnumMap} initialized with the mappings from {@code 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map} 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code m} is not an {@code EnumMap} 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * instance and contains no mappings 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3107dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Map<K, ? extends V> map) { 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EnumMap<K, V>(map); 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an {@code IdentityHashMap} instance. 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code IdentityHashMap} 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() { 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new IdentityHashMap<K, V>(); 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Computes the difference between two maps. This difference is an immutable 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * snapshot of the state of the maps at the time this method is called. It 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will never change, even if the maps change at a later time. 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Since this method uses {@code HashMap} instances internally, the keys of 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the supplied maps must be well-behaved with respect to 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Object#equals} and {@link Object#hashCode}. 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b>If you only need to know whether two maps have the same 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mappings, call {@code left.equals(right)} instead of this method. 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param left the map to treat as the "left" map for purposes of comparison 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param right the map to treat as the "right" map for purposes of comparison 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the difference between the two maps 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 3407dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> MapDifference<K, V> difference(Map<? extends K, ? extends V> left, 3417dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<? extends K, ? extends V> right) { 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (left instanceof SortedMap) { 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, ? extends V> sortedLeft = (SortedMap<K, ? extends V>) left; 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMapDifference<K, V> result = difference(sortedLeft, right); 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3477dd252788645e940eada959bdde927426e2531c9Paul Duffin return difference(left, right, Equivalence.equals()); 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Computes the difference between two maps. This difference is an immutable 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * snapshot of the state of the maps at the time this method is called. It 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will never change, even if the maps change at a later time. 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Values are compared using a provided equivalence, in the case of 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equality, the value on the 'left' is returned in the difference. 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Since this method uses {@code HashMap} instances internally, the keys of 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the supplied maps must be well-behaved with respect to 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Object#equals} and {@link Object#hashCode}. 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param left the map to treat as the "left" map for purposes of comparison 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param right the map to treat as the "right" map for purposes of comparison 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param valueEquivalence the equivalence relationship to use to compare 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the difference between the two maps 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 3707dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> MapDifference<K, V> difference(Map<? extends K, ? extends V> left, 3717dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<? extends K, ? extends V> right, Equivalence<? super V> valueEquivalence) { 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Preconditions.checkNotNull(valueEquivalence); 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> onlyOnLeft = newHashMap(); 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> onlyOnRight = new HashMap<K, V>(right); // will whittle it down 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> onBoth = newHashMap(); 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, MapDifference.ValueDifference<V>> differences = newHashMap(); 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean eq = true; 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<? extends K, ? extends V> entry : left.entrySet()) { 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K leftKey = entry.getKey(); 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V leftValue = entry.getValue(); 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (right.containsKey(leftKey)) { 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V rightValue = onlyOnRight.remove(leftKey); 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (valueEquivalence.equivalent(leftValue, rightValue)) { 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onBoth.put(leftKey, leftValue); 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert eq = false; 3897dd252788645e940eada959bdde927426e2531c9Paul Duffin differences.put(leftKey, ValueDifferenceImpl.create(leftValue, rightValue)); 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert eq = false; 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onlyOnLeft.put(leftKey, leftValue); 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean areEqual = eq && onlyOnRight.isEmpty(); 3987dd252788645e940eada959bdde927426e2531c9Paul Duffin return mapDifference(areEqual, onlyOnLeft, onlyOnRight, onBoth, differences); 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4017dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <K, V> MapDifference<K, V> mapDifference(boolean areEqual, Map<K, V> onlyOnLeft, 4027dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, V> onlyOnRight, Map<K, V> onBoth, Map<K, ValueDifference<V>> differences) { 4037dd252788645e940eada959bdde927426e2531c9Paul Duffin return new MapDifferenceImpl<K, V>(areEqual, Collections.unmodifiableMap(onlyOnLeft), 4047dd252788645e940eada959bdde927426e2531c9Paul Duffin Collections.unmodifiableMap(onlyOnRight), Collections.unmodifiableMap(onBoth), 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableMap(differences)); 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class MapDifferenceImpl<K, V> implements MapDifference<K, V> { 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final boolean areEqual; 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> onlyOnLeft; 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> onlyOnRight; 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> onBoth; 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, ValueDifference<V>> differences; 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4157dd252788645e940eada959bdde927426e2531c9Paul Duffin MapDifferenceImpl(boolean areEqual, Map<K, V> onlyOnLeft, Map<K, V> onlyOnRight, 4167dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, V> onBoth, Map<K, ValueDifference<V>> differences) { 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.areEqual = areEqual; 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.onlyOnLeft = onlyOnLeft; 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.onlyOnRight = onlyOnRight; 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.onBoth = onBoth; 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.differences = differences; 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean areEqual() { 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return areEqual; 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, V> entriesOnlyOnLeft() { 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return onlyOnLeft; 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, V> entriesOnlyOnRight() { 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return onlyOnRight; 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, V> entriesInCommon() { 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return onBoth; 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, ValueDifference<V>> entriesDiffering() { 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return differences; 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4447dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4457dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean equals(Object object) { 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object == this) { 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object instanceof MapDifference) { 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapDifference<?, ?> other = (MapDifference<?, ?>) object; 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entriesOnlyOnLeft().equals(other.entriesOnlyOnLeft()) 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && entriesOnlyOnRight().equals(other.entriesOnlyOnRight()) 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && entriesInCommon().equals(other.entriesInCommon()) 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && entriesDiffering().equals(other.entriesDiffering()); 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4597dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4607dd252788645e940eada959bdde927426e2531c9Paul Duffin public int hashCode() { 4617dd252788645e940eada959bdde927426e2531c9Paul Duffin return Objects.hashCode(entriesOnlyOnLeft(), entriesOnlyOnRight(), entriesInCommon(), 4627dd252788645e940eada959bdde927426e2531c9Paul Duffin entriesDiffering()); 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4657dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4667dd252788645e940eada959bdde927426e2531c9Paul Duffin public String toString() { 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (areEqual) { 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return "equal"; 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert StringBuilder result = new StringBuilder("not equal"); 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!onlyOnLeft.isEmpty()) { 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.append(": only on left=").append(onlyOnLeft); 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!onlyOnRight.isEmpty()) { 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.append(": only on right=").append(onlyOnRight); 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!differences.isEmpty()) { 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.append(": value differences=").append(differences); 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result.toString(); 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4857dd252788645e940eada959bdde927426e2531c9Paul Duffin static class ValueDifferenceImpl<V> implements MapDifference.ValueDifference<V> { 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final V left; 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final V right; 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <V> ValueDifference<V> create(@Nullable V left, @Nullable V right) { 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ValueDifferenceImpl<V>(left, right); 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ValueDifferenceImpl(@Nullable V left, @Nullable V right) { 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.left = left; 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.right = right; 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V leftValue() { 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return left; 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V rightValue() { 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return right; 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5067dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 5077dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean equals(@Nullable Object object) { 5087dd252788645e940eada959bdde927426e2531c9Paul Duffin if (object instanceof MapDifference.ValueDifference) { 5097dd252788645e940eada959bdde927426e2531c9Paul Duffin MapDifference.ValueDifference<?> that = (MapDifference.ValueDifference<?>) object; 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Objects.equal(this.left, that.leftValue()) 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && Objects.equal(this.right, that.rightValue()); 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5167dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 5177dd252788645e940eada959bdde927426e2531c9Paul Duffin public int hashCode() { 5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Objects.hashCode(left, right); 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5217dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 5227dd252788645e940eada959bdde927426e2531c9Paul Duffin public String toString() { 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return "(" + left + ", " + right + ")"; 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Computes the difference between two sorted maps, using the comparator of 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the left map, or {@code Ordering.natural()} if the left map uses the 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * natural ordering of its elements. This difference is an immutable snapshot 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of the state of the maps at the time this method is called. It will never 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * change, even if the maps change at a later time. 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Since this method uses {@code TreeMap} instances internally, the keys of 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the right map must all compare as distinct according to the comparator 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of the left map. 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b>If you only need to know whether two sorted maps have the 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * same mappings, call {@code left.equals(right)} instead of this method. 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param left the map to treat as the "left" map for purposes of comparison 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param right the map to treat as the "right" map for purposes of comparison 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the difference between the two maps 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5467dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> SortedMapDifference<K, V> difference(SortedMap<K, ? extends V> left, 5477dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<? extends K, ? extends V> right) { 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(left); 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(right); 5507dd252788645e940eada959bdde927426e2531c9Paul Duffin Comparator<K> comparator = orNaturalOrder(left.comparator()); 5517dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedMap<K, V> onlyOnLeft = Maps.<K, K, V>newTreeMap(comparator); 5527dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedMap<K, V> onlyOnRight = Maps.<K, K, V>newTreeMap(comparator); 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onlyOnRight.putAll(right); // will whittle it down 5547dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedMap<K, V> onBoth = Maps.<K, K, V>newTreeMap(comparator); 5557dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedMap<K, MapDifference.ValueDifference<V>> differences = 5567dd252788645e940eada959bdde927426e2531c9Paul Duffin Maps.<K, K, MapDifference.ValueDifference<V>>newTreeMap(comparator); 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean eq = true; 5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<? extends K, ? extends V> entry : left.entrySet()) { 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K leftKey = entry.getKey(); 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V leftValue = entry.getValue(); 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (right.containsKey(leftKey)) { 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V rightValue = onlyOnRight.remove(leftKey); 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(leftValue, rightValue)) { 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onBoth.put(leftKey, leftValue); 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert eq = false; 5687dd252788645e940eada959bdde927426e2531c9Paul Duffin differences.put(leftKey, ValueDifferenceImpl.create(leftValue, rightValue)); 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert eq = false; 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onlyOnLeft.put(leftKey, leftValue); 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean areEqual = eq && onlyOnRight.isEmpty(); 5777dd252788645e940eada959bdde927426e2531c9Paul Duffin return sortedMapDifference(areEqual, onlyOnLeft, onlyOnRight, onBoth, differences); 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5807dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <K, V> SortedMapDifference<K, V> sortedMapDifference(boolean areEqual, 5817dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedMap<K, V> onlyOnLeft, SortedMap<K, V> onlyOnRight, SortedMap<K, V> onBoth, 5827dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedMap<K, ValueDifference<V>> differences) { 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new SortedMapDifferenceImpl<K, V>(areEqual, 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableSortedMap(onlyOnLeft), 5857dd252788645e940eada959bdde927426e2531c9Paul Duffin Collections.unmodifiableSortedMap(onlyOnRight), Collections.unmodifiableSortedMap(onBoth), 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableSortedMap(differences)); 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5897dd252788645e940eada959bdde927426e2531c9Paul Duffin static class SortedMapDifferenceImpl<K, V> extends MapDifferenceImpl<K, V> implements 5907dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedMapDifference<K, V> { 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMapDifferenceImpl(boolean areEqual, SortedMap<K, V> onlyOnLeft, 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> onlyOnRight, SortedMap<K, V> onBoth, 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, ValueDifference<V>> differences) { 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(areEqual, onlyOnLeft, onlyOnRight, onBoth, differences); 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5977dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 5987dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, ValueDifference<V>> entriesDiffering() { 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, ValueDifference<V>>) super.entriesDiffering(); 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6027dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 6037dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V> entriesInCommon() { 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V>) super.entriesInCommon(); 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6077dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 6087dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V> entriesOnlyOnLeft() { 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V>) super.entriesOnlyOnLeft(); 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6127dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 6137dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V> entriesOnlyOnRight() { 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V>) super.entriesOnlyOnRight(); 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the specified comparator if not null; otherwise returns {@code 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Ordering.natural()}. This method is an abomination of generics; the only 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * purpose of this method is to contain the ugly type-casting in one place. 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 6247dd252788645e940eada959bdde927426e2531c9Paul Duffin static <E> Comparator<E> orNaturalOrder(@Nullable Comparator<? super E> comparator) { 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (comparator != null) { // can't use ? : because of javac bug 5080917 6267dd252788645e940eada959bdde927426e2531c9Paul Duffin return (Comparator<E>) comparator; 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (Comparator<E>) Ordering.natural(); 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6307dd252788645e940eada959bdde927426e2531c9Paul Duffin 6317dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 6327dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a view of the set as a map, mapping keys from the set according to 6337dd252788645e940eada959bdde927426e2531c9Paul Duffin * the specified function. 6347dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6357dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>Specifically, for each {@code k} in the backing set, the returned map 6367dd252788645e940eada959bdde927426e2531c9Paul Duffin * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code 6377dd252788645e940eada959bdde927426e2531c9Paul Duffin * keySet}, {@code values}, and {@code entrySet} views of the returned map 6387dd252788645e940eada959bdde927426e2531c9Paul Duffin * iterate in the same order as the backing set. 6397dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6407dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>Modifications to the backing set are read through to the returned map. 6417dd252788645e940eada959bdde927426e2531c9Paul Duffin * The returned map supports removal operations if the backing set does. 6427dd252788645e940eada959bdde927426e2531c9Paul Duffin * Removal operations write through to the backing set. The returned map 6437dd252788645e940eada959bdde927426e2531c9Paul Duffin * does not support put operations. 6447dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6457dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p><b>Warning</b>: If the function rejects {@code null}, caution is 6467dd252788645e940eada959bdde927426e2531c9Paul Duffin * required to make sure the set does not contain {@code null}, because the 6477dd252788645e940eada959bdde927426e2531c9Paul Duffin * view cannot stop {@code null} from being added to the set. 6487dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6497dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 6507dd252788645e940eada959bdde927426e2531c9Paul Duffin * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also 6517dd252788645e940eada959bdde927426e2531c9Paul Duffin * of type {@code K}. Using a key type for which this may not hold, such as 6527dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code ArrayList}, may risk a {@code ClassCastException} when calling 6537dd252788645e940eada959bdde927426e2531c9Paul Duffin * methods on the resulting map view. 6547dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6557dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 14.0 6567dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 6577dd252788645e940eada959bdde927426e2531c9Paul Duffin @Beta 6587dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> Map<K, V> asMap(Set<K> set, Function<? super K, V> function) { 6597dd252788645e940eada959bdde927426e2531c9Paul Duffin if (set instanceof SortedSet) { 6607dd252788645e940eada959bdde927426e2531c9Paul Duffin return asMap((SortedSet<K>) set, function); 6617dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 6627dd252788645e940eada959bdde927426e2531c9Paul Duffin return new AsMapView<K, V>(set, function); 6637dd252788645e940eada959bdde927426e2531c9Paul Duffin } 6647dd252788645e940eada959bdde927426e2531c9Paul Duffin } 6657dd252788645e940eada959bdde927426e2531c9Paul Duffin 6667dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 6677dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a view of the sorted set as a map, mapping keys from the set 6687dd252788645e940eada959bdde927426e2531c9Paul Duffin * according to the specified function. 6697dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6707dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>Specifically, for each {@code k} in the backing set, the returned map 6717dd252788645e940eada959bdde927426e2531c9Paul Duffin * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code 6727dd252788645e940eada959bdde927426e2531c9Paul Duffin * keySet}, {@code values}, and {@code entrySet} views of the returned map 6737dd252788645e940eada959bdde927426e2531c9Paul Duffin * iterate in the same order as the backing set. 6747dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6757dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>Modifications to the backing set are read through to the returned map. 6767dd252788645e940eada959bdde927426e2531c9Paul Duffin * The returned map supports removal operations if the backing set does. 6777dd252788645e940eada959bdde927426e2531c9Paul Duffin * Removal operations write through to the backing set. The returned map does 6787dd252788645e940eada959bdde927426e2531c9Paul Duffin * not support put operations. 6797dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6807dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p><b>Warning</b>: If the function rejects {@code null}, caution is 6817dd252788645e940eada959bdde927426e2531c9Paul Duffin * required to make sure the set does not contain {@code null}, because the 6827dd252788645e940eada959bdde927426e2531c9Paul Duffin * view cannot stop {@code null} from being added to the set. 6837dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6847dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 6857dd252788645e940eada959bdde927426e2531c9Paul Duffin * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of 6867dd252788645e940eada959bdde927426e2531c9Paul Duffin * type {@code K}. Using a key type for which this may not hold, such as 6877dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code ArrayList}, may risk a {@code ClassCastException} when calling 6887dd252788645e940eada959bdde927426e2531c9Paul Duffin * methods on the resulting map view. 6897dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6907dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 14.0 6917dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 6927dd252788645e940eada959bdde927426e2531c9Paul Duffin @Beta 6937dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> SortedMap<K, V> asMap(SortedSet<K> set, Function<? super K, V> function) { 6947dd252788645e940eada959bdde927426e2531c9Paul Duffin return new SortedAsMapView<K, V>(set, function); 6957dd252788645e940eada959bdde927426e2531c9Paul Duffin } 6967dd252788645e940eada959bdde927426e2531c9Paul Duffin 6977dd252788645e940eada959bdde927426e2531c9Paul Duffin private static class AsMapView<K, V> extends ImprovedAbstractMap<K, V> { 6987dd252788645e940eada959bdde927426e2531c9Paul Duffin 6997dd252788645e940eada959bdde927426e2531c9Paul Duffin private final Set<K> set; 7007dd252788645e940eada959bdde927426e2531c9Paul Duffin final Function<? super K, V> function; 7017dd252788645e940eada959bdde927426e2531c9Paul Duffin 7027dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<K> backingSet() { 7037dd252788645e940eada959bdde927426e2531c9Paul Duffin return set; 7047dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7057dd252788645e940eada959bdde927426e2531c9Paul Duffin 7067dd252788645e940eada959bdde927426e2531c9Paul Duffin AsMapView(Set<K> set, Function<? super K, V> function) { 7077dd252788645e940eada959bdde927426e2531c9Paul Duffin this.set = checkNotNull(set); 7087dd252788645e940eada959bdde927426e2531c9Paul Duffin this.function = checkNotNull(function); 7097dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7107dd252788645e940eada959bdde927426e2531c9Paul Duffin 7117dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7127dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<K> keySet() { 7137dd252788645e940eada959bdde927426e2531c9Paul Duffin // probably not worth caching 7147dd252788645e940eada959bdde927426e2531c9Paul Duffin return removeOnlySet(backingSet()); 7157dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7167dd252788645e940eada959bdde927426e2531c9Paul Duffin 7177dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7187dd252788645e940eada959bdde927426e2531c9Paul Duffin public Collection<V> values() { 7197dd252788645e940eada959bdde927426e2531c9Paul Duffin // probably not worth caching 7207dd252788645e940eada959bdde927426e2531c9Paul Duffin return Collections2.transform(set, function); 7217dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7227dd252788645e940eada959bdde927426e2531c9Paul Duffin 7237dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7247dd252788645e940eada959bdde927426e2531c9Paul Duffin public int size() { 7257dd252788645e940eada959bdde927426e2531c9Paul Duffin return backingSet().size(); 7267dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7277dd252788645e940eada959bdde927426e2531c9Paul Duffin 7287dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7297dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean containsKey(@Nullable Object key) { 7307dd252788645e940eada959bdde927426e2531c9Paul Duffin return backingSet().contains(key); 7317dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7327dd252788645e940eada959bdde927426e2531c9Paul Duffin 7337dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7347dd252788645e940eada959bdde927426e2531c9Paul Duffin public V get(@Nullable Object key) { 7357dd252788645e940eada959bdde927426e2531c9Paul Duffin if (backingSet().contains(key)) { 7367dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unchecked") 7377dd252788645e940eada959bdde927426e2531c9Paul Duffin // unsafe, but Javadoc warns about it 7387dd252788645e940eada959bdde927426e2531c9Paul Duffin K k = (K) key; 7397dd252788645e940eada959bdde927426e2531c9Paul Duffin return function.apply(k); 7407dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 7417dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 7427dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7437dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7447dd252788645e940eada959bdde927426e2531c9Paul Duffin 7457dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7467dd252788645e940eada959bdde927426e2531c9Paul Duffin public V remove(@Nullable Object key) { 7477dd252788645e940eada959bdde927426e2531c9Paul Duffin if (backingSet().remove(key)) { 7487dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unchecked") 7497dd252788645e940eada959bdde927426e2531c9Paul Duffin // unsafe, but Javadoc warns about it 7507dd252788645e940eada959bdde927426e2531c9Paul Duffin K k = (K) key; 7517dd252788645e940eada959bdde927426e2531c9Paul Duffin return function.apply(k); 7527dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 7537dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 7547dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7557dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7567dd252788645e940eada959bdde927426e2531c9Paul Duffin 7577dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7587dd252788645e940eada959bdde927426e2531c9Paul Duffin public void clear() { 7597dd252788645e940eada959bdde927426e2531c9Paul Duffin backingSet().clear(); 7607dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7617dd252788645e940eada959bdde927426e2531c9Paul Duffin 7627dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7637dd252788645e940eada959bdde927426e2531c9Paul Duffin protected Set<Entry<K, V>> createEntrySet() { 7647dd252788645e940eada959bdde927426e2531c9Paul Duffin return new EntrySet<K, V>() { 7657dd252788645e940eada959bdde927426e2531c9Paul Duffin 7667dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7677dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, V> map() { 7687dd252788645e940eada959bdde927426e2531c9Paul Duffin return AsMapView.this; 7697dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7707dd252788645e940eada959bdde927426e2531c9Paul Duffin 7717dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7727dd252788645e940eada959bdde927426e2531c9Paul Duffin public Iterator<Entry<K, V>> iterator() { 7737dd252788645e940eada959bdde927426e2531c9Paul Duffin return asSetEntryIterator(backingSet(), function); 7747dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7757dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 7767dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7777dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7787dd252788645e940eada959bdde927426e2531c9Paul Duffin 7797dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <K, V> Iterator<Entry<K, V>> asSetEntryIterator( 7807dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<K> set, final Function<? super K, V> function) { 7817dd252788645e940eada959bdde927426e2531c9Paul Duffin return new TransformedIterator<K, Entry<K,V>>(set.iterator()) { 7827dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7837dd252788645e940eada959bdde927426e2531c9Paul Duffin Entry<K, V> transform(K key) { 7847dd252788645e940eada959bdde927426e2531c9Paul Duffin return Maps.immutableEntry(key, function.apply(key)); 7857dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7867dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 7877dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7887dd252788645e940eada959bdde927426e2531c9Paul Duffin 7897dd252788645e940eada959bdde927426e2531c9Paul Duffin private static class SortedAsMapView<K, V> extends AsMapView<K, V> implements SortedMap<K, V> { 7907dd252788645e940eada959bdde927426e2531c9Paul Duffin 7917dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedAsMapView(SortedSet<K> set, Function<? super K, V> function) { 7927dd252788645e940eada959bdde927426e2531c9Paul Duffin super(set, function); 7937dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7947dd252788645e940eada959bdde927426e2531c9Paul Duffin 7957dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 7967dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedSet<K> backingSet() { 7977dd252788645e940eada959bdde927426e2531c9Paul Duffin return (SortedSet<K>) super.backingSet(); 7987dd252788645e940eada959bdde927426e2531c9Paul Duffin } 7997dd252788645e940eada959bdde927426e2531c9Paul Duffin 8007dd252788645e940eada959bdde927426e2531c9Paul Duffin public Comparator<? super K> comparator() { 8017dd252788645e940eada959bdde927426e2531c9Paul Duffin return backingSet().comparator(); 8027dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8037dd252788645e940eada959bdde927426e2531c9Paul Duffin 8047dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8057dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<K> keySet() { 8067dd252788645e940eada959bdde927426e2531c9Paul Duffin return removeOnlySortedSet(backingSet()); 8077dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8087dd252788645e940eada959bdde927426e2531c9Paul Duffin 8097dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V> subMap(K fromKey, K toKey) { 8107dd252788645e940eada959bdde927426e2531c9Paul Duffin return asMap(backingSet().subSet(fromKey, toKey), function); 8117dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8127dd252788645e940eada959bdde927426e2531c9Paul Duffin 8137dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V> headMap(K toKey) { 8147dd252788645e940eada959bdde927426e2531c9Paul Duffin return asMap(backingSet().headSet(toKey), function); 8157dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8167dd252788645e940eada959bdde927426e2531c9Paul Duffin 8177dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V> tailMap(K fromKey) { 8187dd252788645e940eada959bdde927426e2531c9Paul Duffin return asMap(backingSet().tailSet(fromKey), function); 8197dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8207dd252788645e940eada959bdde927426e2531c9Paul Duffin 8217dd252788645e940eada959bdde927426e2531c9Paul Duffin public K firstKey() { 8227dd252788645e940eada959bdde927426e2531c9Paul Duffin return backingSet().first(); 8237dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8247dd252788645e940eada959bdde927426e2531c9Paul Duffin 8257dd252788645e940eada959bdde927426e2531c9Paul Duffin public K lastKey() { 8267dd252788645e940eada959bdde927426e2531c9Paul Duffin return backingSet().last(); 8277dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8287dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8297dd252788645e940eada959bdde927426e2531c9Paul Duffin 8307dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <E> Set<E> removeOnlySet(final Set<E> set) { 8317dd252788645e940eada959bdde927426e2531c9Paul Duffin return new ForwardingSet<E>() { 8327dd252788645e940eada959bdde927426e2531c9Paul Duffin 8337dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8347dd252788645e940eada959bdde927426e2531c9Paul Duffin protected Set<E> delegate() { 8357dd252788645e940eada959bdde927426e2531c9Paul Duffin return set; 8367dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8377dd252788645e940eada959bdde927426e2531c9Paul Duffin 8387dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8397dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean add(E element) { 8407dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new UnsupportedOperationException(); 8417dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8427dd252788645e940eada959bdde927426e2531c9Paul Duffin 8437dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8447dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean addAll(Collection<? extends E> es) { 8457dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new UnsupportedOperationException(); 8467dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8477dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 8487dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8497dd252788645e940eada959bdde927426e2531c9Paul Duffin 8507dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <E> SortedSet<E> removeOnlySortedSet(final SortedSet<E> set) { 8517dd252788645e940eada959bdde927426e2531c9Paul Duffin return new ForwardingSortedSet<E>() { 8527dd252788645e940eada959bdde927426e2531c9Paul Duffin 8537dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8547dd252788645e940eada959bdde927426e2531c9Paul Duffin protected SortedSet<E> delegate() { 8557dd252788645e940eada959bdde927426e2531c9Paul Duffin return set; 8567dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8577dd252788645e940eada959bdde927426e2531c9Paul Duffin 8587dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8597dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean add(E element) { 8607dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new UnsupportedOperationException(); 8617dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8627dd252788645e940eada959bdde927426e2531c9Paul Duffin 8637dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8647dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean addAll(Collection<? extends E> es) { 8657dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new UnsupportedOperationException(); 8667dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8677dd252788645e940eada959bdde927426e2531c9Paul Duffin 8687dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8697dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedSet<E> headSet(E toElement) { 8707dd252788645e940eada959bdde927426e2531c9Paul Duffin return removeOnlySortedSet(super.headSet(toElement)); 8717dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8727dd252788645e940eada959bdde927426e2531c9Paul Duffin 8737dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8747dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedSet<E> subSet(E fromElement, E toElement) { 8757dd252788645e940eada959bdde927426e2531c9Paul Duffin return removeOnlySortedSet(super.subSet(fromElement, toElement)); 8767dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8777dd252788645e940eada959bdde927426e2531c9Paul Duffin 8787dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 8797dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedSet<E> tailSet(E fromElement) { 8807dd252788645e940eada959bdde927426e2531c9Paul Duffin return removeOnlySortedSet(super.tailSet(fromElement)); 8817dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8827dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 8837dd252788645e940eada959bdde927426e2531c9Paul Duffin } 8847dd252788645e940eada959bdde927426e2531c9Paul Duffin 8857dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 8867dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns an immutable map for which the given {@code keys} are mapped to 8877dd252788645e940eada959bdde927426e2531c9Paul Duffin * values by the given function in the order they appear in the original 8887dd252788645e940eada959bdde927426e2531c9Paul Duffin * iterable. If {@code keys} contains duplicate elements, the returned map 8897dd252788645e940eada959bdde927426e2531c9Paul Duffin * will contain each distinct key once in the order it first appears in 8907dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code keys}. 8917dd252788645e940eada959bdde927426e2531c9Paul Duffin * 8927dd252788645e940eada959bdde927426e2531c9Paul Duffin * @throws NullPointerException if any element of {@code keys} is 8937dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code null}, or if {@code valueFunction} produces {@code null} 8947dd252788645e940eada959bdde927426e2531c9Paul Duffin * for any key 8957dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 14.0 8967dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 8977dd252788645e940eada959bdde927426e2531c9Paul Duffin @Beta 8987dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> ImmutableMap<K, V> toMap(Iterable<K> keys, 8997dd252788645e940eada959bdde927426e2531c9Paul Duffin Function<? super K, V> valueFunction) { 9007dd252788645e940eada959bdde927426e2531c9Paul Duffin return toMap(keys.iterator(), valueFunction); 9017dd252788645e940eada959bdde927426e2531c9Paul Duffin } 9027dd252788645e940eada959bdde927426e2531c9Paul Duffin 9037dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 9047dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns an immutable map for which the given {@code keys} are mapped to 9057dd252788645e940eada959bdde927426e2531c9Paul Duffin * values by the given function in the order they appear in the original 9067dd252788645e940eada959bdde927426e2531c9Paul Duffin * iterator. If {@code keys} contains duplicate elements, the returned map 9077dd252788645e940eada959bdde927426e2531c9Paul Duffin * will contain each distinct key once in the order it first appears in 9087dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code keys}. 9097dd252788645e940eada959bdde927426e2531c9Paul Duffin * 9107dd252788645e940eada959bdde927426e2531c9Paul Duffin * @throws NullPointerException if any element of {@code keys} is 9117dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code null}, or if {@code valueFunction} produces {@code null} 9127dd252788645e940eada959bdde927426e2531c9Paul Duffin * for any key 9137dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 14.0 9147dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 9157dd252788645e940eada959bdde927426e2531c9Paul Duffin @Beta 9167dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> ImmutableMap<K, V> toMap(Iterator<K> keys, 9177dd252788645e940eada959bdde927426e2531c9Paul Duffin Function<? super K, V> valueFunction) { 9187dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(valueFunction); 9197dd252788645e940eada959bdde927426e2531c9Paul Duffin // Using LHM instead of a builder so as not to fail on duplicate keys 9207dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, V> builder = newLinkedHashMap(); 9217dd252788645e940eada959bdde927426e2531c9Paul Duffin while (keys.hasNext()) { 9227dd252788645e940eada959bdde927426e2531c9Paul Duffin K key = keys.next(); 9237dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.put(key, valueFunction.apply(key)); 9247dd252788645e940eada959bdde927426e2531c9Paul Duffin } 9257dd252788645e940eada959bdde927426e2531c9Paul Duffin return ImmutableMap.copyOf(builder); 9267dd252788645e940eada959bdde927426e2531c9Paul Duffin } 9277dd252788645e940eada959bdde927426e2531c9Paul Duffin 9281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 929dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an immutable map for which the {@link Map#values} are the given 930dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * elements in the given order, and each key is the product of invoking a 931dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * supplied function on its corresponding value. 9323c77433663281544363151bf284b0240dfd22a42Paul Duffin * 933dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param values the values to use when constructing the {@code Map} 934dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param keyFunction the function used to produce the key for each value 935dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return a map mapping the result of evaluating the function {@code 936dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * keyFunction} on each value in the input collection to that value 937dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws IllegalArgumentException if {@code keyFunction} produces the same 938dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * key for more than one value in the input collection 939dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws NullPointerException if any elements of {@code values} is null, or 940dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * if {@code keyFunction} produces {@code null} for any value 9411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 9427dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> ImmutableMap<K, V> uniqueIndex(Iterable<V> values, 9437dd252788645e940eada959bdde927426e2531c9Paul Duffin Function<? super V, K> keyFunction) { 944dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return uniqueIndex(values.iterator(), keyFunction); 9451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 948dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an immutable map for which the {@link Map#values} are the given 949dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * elements in the given order, and each key is the product of invoking a 950dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * supplied function on its corresponding value. 9513c77433663281544363151bf284b0240dfd22a42Paul Duffin * 952dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param values the values to use when constructing the {@code Map} 953dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param keyFunction the function used to produce the key for each value 954dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return a map mapping the result of evaluating the function {@code 955dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * keyFunction} on each value in the input collection to that value 956dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws IllegalArgumentException if {@code keyFunction} produces the same 957dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * key for more than one value in the input collection 958dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws NullPointerException if any elements of {@code values} is null, or 959dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * if {@code keyFunction} produces {@code null} for any value 960dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @since 10.0 9611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 9627dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> ImmutableMap<K, V> uniqueIndex(Iterator<V> values, 9637dd252788645e940eada959bdde927426e2531c9Paul Duffin Function<? super V, K> keyFunction) { 964dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin checkNotNull(keyFunction); 965dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin ImmutableMap.Builder<K, V> builder = ImmutableMap.builder(); 966dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin while (values.hasNext()) { 967dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin V value = values.next(); 968dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin builder.put(keyFunction.apply(value), value); 9693c77433663281544363151bf284b0240dfd22a42Paul Duffin } 970dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return builder.build(); 971dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 9721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 973dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 974dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Creates an {@code ImmutableMap<String, String>} from a {@code Properties} 975dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * instance. Properties normally derive from {@code Map<Object, Object>}, but 976dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * they typically contain strings, which is awkward. This method lets you get 977dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * a plain-old-{@code Map} out of a {@code Properties}. 978dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 979dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param properties a {@code Properties} object to be converted 980dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return an immutable map containing all the entries in {@code properties} 981dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws ClassCastException if any key in {@code Properties} is not a {@code 982dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * String} 983dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws NullPointerException if any key or value in {@code Properties} is 984dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * null 985dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 986dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @GwtIncompatible("java.util.Properties") 9877dd252788645e940eada959bdde927426e2531c9Paul Duffin public static ImmutableMap<String, String> fromProperties(Properties properties) { 988dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); 9891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 990dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) { 991dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin String key = (String) e.nextElement(); 992dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin builder.put(key, properties.getProperty(key)); 9931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 995dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return builder.build(); 996dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 9971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 998dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 999dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an immutable map entry with the specified key and value. The {@link 1000dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 1001dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 1002dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * <p>The returned entry is serializable. 1003dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 1004dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param key the key to be associated with the returned entry 1005dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param value the value to be associated with the returned entry 1006dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 1007dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @GwtCompatible(serializable = true) 10087dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> Entry<K, V> immutableEntry(@Nullable K key, @Nullable V value) { 1009dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return new ImmutableEntry<K, V>(key, value); 1010dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 10113c77433663281544363151bf284b0240dfd22a42Paul Duffin 1012dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 1013dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an unmodifiable view of the specified set of entries. The {@link 1014dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Entry#setValue} operation throws an {@link UnsupportedOperationException}, 1015dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * as do any operations that would modify the returned set. 1016dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 1017dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param entrySet the entries for which to return an unmodifiable view 1018dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return an unmodifiable view of the entries 1019dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 10207dd252788645e940eada959bdde927426e2531c9Paul Duffin static <K, V> Set<Entry<K, V>> unmodifiableEntrySet(Set<Entry<K, V>> entrySet) { 10217dd252788645e940eada959bdde927426e2531c9Paul Duffin return new UnmodifiableEntrySet<K, V>(Collections.unmodifiableSet(entrySet)); 1022dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 10233c77433663281544363151bf284b0240dfd22a42Paul Duffin 1024dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 1025dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an unmodifiable view of the specified map entry. The {@link 1026dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 1027dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * This also has the side-effect of redefining {@code equals} to comply with 1028dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * the Entry contract, to avoid a possible nefarious implementation of equals. 1029dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 1030dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param entry the entry for which to return an unmodifiable view 1031dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return an unmodifiable view of the entry 1032dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 1033dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin static <K, V> Entry<K, V> unmodifiableEntry(final Entry<K, V> entry) { 1034dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin checkNotNull(entry); 1035dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return new AbstractMapEntry<K, V>() { 10367dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10377dd252788645e940eada959bdde927426e2531c9Paul Duffin public K getKey() { 1038dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return entry.getKey(); 10393c77433663281544363151bf284b0240dfd22a42Paul Duffin } 10403c77433663281544363151bf284b0240dfd22a42Paul Duffin 10417dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10427dd252788645e940eada959bdde927426e2531c9Paul Duffin public V getValue() { 1043dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return entry.getValue(); 10443c77433663281544363151bf284b0240dfd22a42Paul Duffin } 1045dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }; 1046dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1047dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 1048dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** @see Multimaps#unmodifiableEntries */ 10497dd252788645e940eada959bdde927426e2531c9Paul Duffin static class UnmodifiableEntries<K, V> extends ForwardingCollection<Entry<K, V>> { 1050dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin private final Collection<Entry<K, V>> entries; 1051dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 1052dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin UnmodifiableEntries(Collection<Entry<K, V>> entries) { 1053dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin this.entries = entries; 10543c77433663281544363151bf284b0240dfd22a42Paul Duffin } 10553c77433663281544363151bf284b0240dfd22a42Paul Duffin 10567dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10577dd252788645e940eada959bdde927426e2531c9Paul Duffin protected Collection<Entry<K, V>> delegate() { 1058dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return entries; 10593c77433663281544363151bf284b0240dfd22a42Paul Duffin } 10603c77433663281544363151bf284b0240dfd22a42Paul Duffin 10617dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10627dd252788645e940eada959bdde927426e2531c9Paul Duffin public Iterator<Entry<K, V>> iterator() { 1063dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin final Iterator<Entry<K, V>> delegate = super.iterator(); 1064dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return new ForwardingIterator<Entry<K, V>>() { 10657dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10667dd252788645e940eada959bdde927426e2531c9Paul Duffin public Entry<K, V> next() { 1067dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return unmodifiableEntry(super.next()); 10681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10707dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10717dd252788645e940eada959bdde927426e2531c9Paul Duffin public void remove() { 1072dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 1073dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1074dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 10757dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10767dd252788645e940eada959bdde927426e2531c9Paul Duffin protected Iterator<Entry<K, V>> delegate() { 1077dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return delegate; 10781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 10801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1082dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin // See java.util.Collections.UnmodifiableEntrySet for details on attacks. 10831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10847dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10857dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean add(Entry<K, V> element) { 1086dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10897dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10907dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean addAll(Collection<? extends Entry<K, V>> collection) { 1091dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 10921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10947dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10957dd252788645e940eada959bdde927426e2531c9Paul Duffin public void clear() { 1096dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 10971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10997dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 11007dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean remove(Object object) { 1101dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 11021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11047dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 11057dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean removeAll(Collection<?> collection) { 1106dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 11071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11097dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 11107dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean retainAll(Collection<?> collection) { 1111dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 11121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11147dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 11157dd252788645e940eada959bdde927426e2531c9Paul Duffin public Object[] toArray() { 1116dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return standardToArray(); 11173c77433663281544363151bf284b0240dfd22a42Paul Duffin } 11183c77433663281544363151bf284b0240dfd22a42Paul Duffin 11197dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 11207dd252788645e940eada959bdde927426e2531c9Paul Duffin public <T> T[] toArray(T[] array) { 1121dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return standardToArray(array); 11221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see Maps#unmodifiableEntrySet(Set) */ 11267dd252788645e940eada959bdde927426e2531c9Paul Duffin static class UnmodifiableEntrySet<K, V> extends UnmodifiableEntries<K, V> implements 11277dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<Entry<K, V>> { 11281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableEntrySet(Set<Entry<K, V>> entries) { 11291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(entries); 11301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // See java.util.Collections.UnmodifiableEntrySet for details on attacks. 11331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11347dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 11357dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean equals(@Nullable Object object) { 11361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.equalsImpl(this, object); 11371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11397dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 11407dd252788645e940eada959bdde927426e2531c9Paul Duffin public int hashCode() { 11411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.hashCodeImpl(this); 11421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 11467dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a synchronized (thread-safe) bimap backed by the specified bimap. 11477dd252788645e940eada959bdde927426e2531c9Paul Duffin * In order to guarantee serial access, it is critical that <b>all</b> access 11487dd252788645e940eada959bdde927426e2531c9Paul Duffin * to the backing bimap is accomplished through the returned bimap. 11497dd252788645e940eada959bdde927426e2531c9Paul Duffin * 11507dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>It is imperative that the user manually synchronize on the returned map 11517dd252788645e940eada959bdde927426e2531c9Paul Duffin * when accessing any of its collection views: <pre> {@code 11527dd252788645e940eada959bdde927426e2531c9Paul Duffin * 11537dd252788645e940eada959bdde927426e2531c9Paul Duffin * BiMap<Long, String> map = Maps.synchronizedBiMap( 11547dd252788645e940eada959bdde927426e2531c9Paul Duffin * HashBiMap.<Long, String>create()); 11557dd252788645e940eada959bdde927426e2531c9Paul Duffin * ... 11567dd252788645e940eada959bdde927426e2531c9Paul Duffin * Set<Long> set = map.keySet(); // Needn't be in synchronized block 11577dd252788645e940eada959bdde927426e2531c9Paul Duffin * ... 11587dd252788645e940eada959bdde927426e2531c9Paul Duffin * synchronized (map) { // Synchronizing on map, not set! 11597dd252788645e940eada959bdde927426e2531c9Paul Duffin * Iterator<Long> it = set.iterator(); // Must be in synchronized block 11607dd252788645e940eada959bdde927426e2531c9Paul Duffin * while (it.hasNext()) { 11617dd252788645e940eada959bdde927426e2531c9Paul Duffin * foo(it.next()); 11627dd252788645e940eada959bdde927426e2531c9Paul Duffin * } 11637dd252788645e940eada959bdde927426e2531c9Paul Duffin * }}</pre> 11647dd252788645e940eada959bdde927426e2531c9Paul Duffin * 11657dd252788645e940eada959bdde927426e2531c9Paul Duffin * Failure to follow this advice may result in non-deterministic behavior. 11667dd252788645e940eada959bdde927426e2531c9Paul Duffin * 11677dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>The returned bimap will be serializable if the specified bimap is 11687dd252788645e940eada959bdde927426e2531c9Paul Duffin * serializable. 11697dd252788645e940eada959bdde927426e2531c9Paul Duffin * 11707dd252788645e940eada959bdde927426e2531c9Paul Duffin * @param bimap the bimap to be wrapped in a synchronized view 11717dd252788645e940eada959bdde927426e2531c9Paul Duffin * @return a sychronized view of the specified bimap 11727dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 11737dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) { 11747dd252788645e940eada959bdde927426e2531c9Paul Duffin return Synchronized.biMap(bimap, null); 11757dd252788645e940eada959bdde927426e2531c9Paul Duffin } 11767dd252788645e940eada959bdde927426e2531c9Paul Duffin 11777dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 11781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified bimap. This method allows 11791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modules to provide users with "read-only" access to internal bimaps. Query 11801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * operations on the returned bimap "read through" to the specified bimap, and 11811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * attempts to modify the returned map, whether direct or via its collection 11821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * views, result in an {@code UnsupportedOperationException}. 11831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned bimap will be serializable if the specified bimap is 11851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 11861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param bimap the bimap for which an unmodifiable view is to be returned 11881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified bimap 11891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 11907dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> BiMap<K, V> unmodifiableBiMap(BiMap<? extends K, ? extends V> bimap) { 11911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableBiMap<K, V>(bimap, null); 11921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see Maps#unmodifiableBiMap(BiMap) */ 11957dd252788645e940eada959bdde927426e2531c9Paul Duffin private static class UnmodifiableBiMap<K, V> extends ForwardingMap<K, V> implements BiMap<K, V>, 11967dd252788645e940eada959bdde927426e2531c9Paul Duffin Serializable { 11971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> unmodifiableMap; 11981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final BiMap<? extends K, ? extends V> delegate; 11997dd252788645e940eada959bdde927426e2531c9Paul Duffin BiMap<V, K> inverse; 12001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Set<V> values; 12011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12027dd252788645e940eada959bdde927426e2531c9Paul Duffin UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate, @Nullable BiMap<V, K> inverse) { 12031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert unmodifiableMap = Collections.unmodifiableMap(delegate); 12041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = delegate; 12051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.inverse = inverse; 12061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12087dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 12097dd252788645e940eada959bdde927426e2531c9Paul Duffin protected Map<K, V> delegate() { 12101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unmodifiableMap; 12111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V forcePut(K key, V value) { 12141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 12151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public BiMap<V, K> inverse() { 12181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BiMap<V, K> result = inverse; 12197dd252788645e940eada959bdde927426e2531c9Paul Duffin return (result == null) ? inverse = new UnmodifiableBiMap<V, K>(delegate.inverse(), this) 12201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : result; 12211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12237dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 12247dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<V> values() { 12251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<V> result = values; 12267dd252788645e940eada959bdde927426e2531c9Paul Duffin return (result == null) ? values = Collections.unmodifiableSet(delegate.values()) : result; 12271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 12301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 12331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a map where each value is transformed by a function. All 12341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other properties of the map, such as iteration order, are left intact. For 12351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * example, the code: <pre> {@code 12361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9); 12381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<Integer, Double> sqrt = 12391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new Function<Integer, Double>() { 12401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public Double apply(Integer in) { 12411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return Math.sqrt((int) in); 12421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 12431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 12441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map<String, Double> transformed = Maps.transformValues(map, sqrt); 12451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 12461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {a=2.0, b=3.0}}. 12481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying map are reflected in this view. Conversely, 12501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this view supports removal operations, and these are reflected in the 12511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map. 12521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying map to contain null keys, and even 12541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null values provided that the function is capable of accepting null input. 12551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The transformed map might contain null values, if the function sometimes 12561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * gives a null result. 12571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map is not thread-safe or serializable, even if the 12591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map is. 12601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The function is applied lazily, invoked when needed. This is necessary 12621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for the returned map to be a view, but it means that the function will be 12631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * applied many times for bulk operations like {@link Map#containsValue} and 12641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Map.toString()}. For this to perform well, {@code function} should 12651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be fast. To avoid lazy evaluation when the returned map doesn't need to be 12661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a view, copy the returned map into a new map of your choosing. 12671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 12687dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V1, V2> Map<K, V2> transformValues(Map<K, V1> fromMap, 12697dd252788645e940eada959bdde927426e2531c9Paul Duffin Function<? super V1, V2> function) { 12707dd252788645e940eada959bdde927426e2531c9Paul Duffin return transformEntries(fromMap, asEntryTransformer(function)); 12711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 12741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a sorted map where each value is transformed by a 12751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function. All other properties of the map, such as iteration order, are 12761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * left intact. For example, the code: <pre> {@code 12771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9); 12791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<Integer, Double> sqrt = 12801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new Function<Integer, Double>() { 12811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public Double apply(Integer in) { 12821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return Math.sqrt((int) in); 12831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 12841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 12851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * SortedMap<String, Double> transformed = 12861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Maps.transformSortedValues(map, sqrt); 12871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 12881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {a=2.0, b=3.0}}. 12901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying map are reflected in this view. Conversely, 12921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this view supports removal operations, and these are reflected in the 12931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map. 12941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying map to contain null keys, and even 12961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null values provided that the function is capable of accepting null input. 12971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The transformed map might contain null values, if the function sometimes 12981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * gives a null result. 12991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map is not thread-safe or serializable, even if the 13011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map is. 13021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The function is applied lazily, invoked when needed. This is necessary 13041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for the returned map to be a view, but it means that the function will be 13051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * applied many times for bulk operations like {@link Map#containsValue} and 13061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Map.toString()}. For this to perform well, {@code function} should 13071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be fast. To avoid lazy evaluation when the returned map doesn't need to be 13081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a view, copy the returned map into a new map of your choosing. 13091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 13111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 13127dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V1, V2> SortedMap<K, V2> transformValues(SortedMap<K, V1> fromMap, 13137dd252788645e940eada959bdde927426e2531c9Paul Duffin Function<? super V1, V2> function) { 13147dd252788645e940eada959bdde927426e2531c9Paul Duffin return transformEntries(fromMap, asEntryTransformer(function)); 13157dd252788645e940eada959bdde927426e2531c9Paul Duffin } 13167dd252788645e940eada959bdde927426e2531c9Paul Duffin 13177dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <K, V1, V2> EntryTransformer<K, V1, V2> asEntryTransformer( 13187dd252788645e940eada959bdde927426e2531c9Paul Duffin final Function<? super V1, V2> function) { 13191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(function); 13207dd252788645e940eada959bdde927426e2531c9Paul Duffin return new EntryTransformer<K, V1, V2>() { 13217dd252788645e940eada959bdde927426e2531c9Paul Duffin 13227dd252788645e940eada959bdde927426e2531c9Paul Duffin public V2 transformEntry(K key, V1 value) { 13237dd252788645e940eada959bdde927426e2531c9Paul Duffin return function.apply(value); 13247dd252788645e940eada959bdde927426e2531c9Paul Duffin } 13257dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 13261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1328dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 1329dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns a view of a map whose values are derived from the original map's 1330dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * entries. In contrast to {@link #transformValues}, this method's 1331dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * entry-transformation logic may depend on the key as well as the value. 13321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>All other properties of the transformed map, such as iteration order, 13341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * are left intact. For example, the code: <pre> {@code 13351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map<String, Boolean> options = 1337dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * ImmutableMap.of("verbose", true, "sort", false); 13381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer<String, Boolean, String> flagPrefixer = 13391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new EntryTransformer<String, Boolean, String>() { 13401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public String transformEntry(String key, Boolean value) { 1341dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * return value ? key : "no" + key; 13421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 13431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 1344dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Map<String, String> transformed = 1345dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Maps.transformEntries(options, flagPrefixer); 13461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 13471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1348dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * ... prints {@code {verbose=verbose, sort=nosort}}. 13491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying map are reflected in this view. Conversely, 13511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this view supports removal operations, and these are reflected in the 13521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map. 13531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying map to contain null keys and null 13551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values provided that the transformer is capable of accepting null inputs. 13561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The transformed map might contain null values if the transformer sometimes 13571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * gives a null result. 13581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map is not thread-safe or serializable, even if the 13601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map is. 13611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The transformer is applied lazily, invoked when needed. This is 13631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * necessary for the returned map to be a view, but it means that the 13641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer will be applied many times for bulk operations like {@link 13651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map#containsValue} and {@link Object#toString}. For this to perform well, 13661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code transformer} should be fast. To avoid lazy evaluation when the 13671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned map doesn't need to be a view, copy the returned map into a new 13681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map of your choosing. 13691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 13711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 13721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that {@code k2} is also of type {@code K}. Using an {@code 13731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer} key type for which this may not hold, such as {@code 13741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ArrayList}, may risk a {@code ClassCastException} when calling methods on 13751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the transformed map. 13761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1377dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @since 7.0 13781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 13797dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V1, V2> Map<K, V2> transformEntries(Map<K, V1> fromMap, 13803c77433663281544363151bf284b0240dfd22a42Paul Duffin EntryTransformer<? super K, ? super V1, V2> transformer) { 1381dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin if (fromMap instanceof SortedMap) { 1382dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return transformEntries((SortedMap<K, V1>) fromMap, transformer); 1383dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1384dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return new TransformedEntriesMap<K, V1, V2>(fromMap, transformer); 13853c77433663281544363151bf284b0240dfd22a42Paul Duffin } 13863c77433663281544363151bf284b0240dfd22a42Paul Duffin 13873c77433663281544363151bf284b0240dfd22a42Paul Duffin /** 1388dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns a view of a sorted map whose values are derived from the original 1389dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * sorted map's entries. In contrast to {@link #transformValues}, this 1390dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * method's entry-transformation logic may depend on the key as well as the 1391dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * value. 13923c77433663281544363151bf284b0240dfd22a42Paul Duffin * 13933c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p>All other properties of the transformed map, such as iteration order, 13943c77433663281544363151bf284b0240dfd22a42Paul Duffin * are left intact. For example, the code: <pre> {@code 13953c77433663281544363151bf284b0240dfd22a42Paul Duffin * 1396dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Map<String, Boolean> options = 1397dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * ImmutableSortedMap.of("verbose", true, "sort", false); 13983c77433663281544363151bf284b0240dfd22a42Paul Duffin * EntryTransformer<String, Boolean, String> flagPrefixer = 13993c77433663281544363151bf284b0240dfd22a42Paul Duffin * new EntryTransformer<String, Boolean, String>() { 14003c77433663281544363151bf284b0240dfd22a42Paul Duffin * public String transformEntry(String key, Boolean value) { 1401dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * return value ? key : "yes" + key; 14023c77433663281544363151bf284b0240dfd22a42Paul Duffin * } 14033c77433663281544363151bf284b0240dfd22a42Paul Duffin * }; 1404dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * SortedMap<String, String> transformed = 1405dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * LabsMaps.transformSortedEntries(options, flagPrefixer); 14063c77433663281544363151bf284b0240dfd22a42Paul Duffin * System.out.println(transformed);}</pre> 14073c77433663281544363151bf284b0240dfd22a42Paul Duffin * 14083c77433663281544363151bf284b0240dfd22a42Paul Duffin * ... prints {@code {sort=yessort, verbose=verbose}}. 14093c77433663281544363151bf284b0240dfd22a42Paul Duffin * 1410dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * <p>Changes in the underlying map are reflected in this view. Conversely, 1411dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * this view supports removal operations, and these are reflected in the 1412dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * underlying map. 14133c77433663281544363151bf284b0240dfd22a42Paul Duffin * 14143c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p>It's acceptable for the underlying map to contain null keys and null 14153c77433663281544363151bf284b0240dfd22a42Paul Duffin * values provided that the transformer is capable of accepting null inputs. 14163c77433663281544363151bf284b0240dfd22a42Paul Duffin * The transformed map might contain null values if the transformer sometimes 14173c77433663281544363151bf284b0240dfd22a42Paul Duffin * gives a null result. 14183c77433663281544363151bf284b0240dfd22a42Paul Duffin * 14193c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p>The returned map is not thread-safe or serializable, even if the 14203c77433663281544363151bf284b0240dfd22a42Paul Duffin * underlying map is. 14213c77433663281544363151bf284b0240dfd22a42Paul Duffin * 14223c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p>The transformer is applied lazily, invoked when needed. This is 14233c77433663281544363151bf284b0240dfd22a42Paul Duffin * necessary for the returned map to be a view, but it means that the 14243c77433663281544363151bf284b0240dfd22a42Paul Duffin * transformer will be applied many times for bulk operations like {@link 14253c77433663281544363151bf284b0240dfd22a42Paul Duffin * Map#containsValue} and {@link Object#toString}. For this to perform well, 14263c77433663281544363151bf284b0240dfd22a42Paul Duffin * {@code transformer} should be fast. To avoid lazy evaluation when the 14273c77433663281544363151bf284b0240dfd22a42Paul Duffin * returned map doesn't need to be a view, copy the returned map into a new 14283c77433663281544363151bf284b0240dfd22a42Paul Duffin * map of your choosing. 14293c77433663281544363151bf284b0240dfd22a42Paul Duffin * 14303c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 14313c77433663281544363151bf284b0240dfd22a42Paul Duffin * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 14323c77433663281544363151bf284b0240dfd22a42Paul Duffin * that {@code k2} is also of type {@code K}. Using an {@code 14333c77433663281544363151bf284b0240dfd22a42Paul Duffin * EntryTransformer} key type for which this may not hold, such as {@code 14343c77433663281544363151bf284b0240dfd22a42Paul Duffin * ArrayList}, may risk a {@code ClassCastException} when calling methods on 14353c77433663281544363151bf284b0240dfd22a42Paul Duffin * the transformed map. 14363c77433663281544363151bf284b0240dfd22a42Paul Duffin * 1437dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @since 11.0 14383c77433663281544363151bf284b0240dfd22a42Paul Duffin */ 14397dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V1, V2> SortedMap<K, V2> transformEntries(SortedMap<K, V1> fromMap, 14401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 14411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TransformedEntriesSortedMap<K, V1, V2>(fromMap, transformer); 14421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 14451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A transformation of the value of a key-value pair, using both key and value 14461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * as inputs. To apply the transformation to a map, use 14471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Maps#transformEntries(Map, EntryTransformer)}. 14481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param <K> the key type of the input and output entries 14501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @paramthe value type of the input entry 14511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param the value type of the output entry 14521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 14531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 14541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public interface EntryTransformer<K, V1, V2> { 14551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 14561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Determines an output value based on a key-value pair. This method is 14571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <i>generally expected</i>, but not absolutely required, to have the 14581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * following properties: 14591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <ul> 14611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>Its execution does not cause any observable side effects. 14621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>The computation is <i>consistent with equals</i>; that is, 14631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Objects#equal Objects.equal}{@code (k1, k2) &&} 14641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Objects#equal}{@code (v1, v2)} implies that {@code 14651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Objects.equal(transformer.transform(k1, v1), 14661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer.transform(k2, v2))}. 14671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * </ul> 14681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if the key or value is null and this 14701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer does not accept null arguments 14711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 14721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V2 transformEntry(@Nullable K key, @Nullable V1 value); 14731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14757dd252788645e940eada959bdde927426e2531c9Paul Duffin static class TransformedEntriesMap<K, V1, V2> extends AbstractMap<K, V2> { 14761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V1> fromMap; 14771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final EntryTransformer<? super K, ? super V1, V2> transformer; 14781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14797dd252788645e940eada959bdde927426e2531c9Paul Duffin TransformedEntriesMap(Map<K, V1> fromMap, 14801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 14811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.fromMap = checkNotNull(fromMap); 14821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.transformer = checkNotNull(transformer); 14831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14857dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 14867dd252788645e940eada959bdde927426e2531c9Paul Duffin public int size() { 14871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap.size(); 14881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14907dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 14917dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean containsKey(Object key) { 14921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap.containsKey(key); 14931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // safe as long as the user followed the <b>Warning</b> in the javadoc 14967dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 14971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 14987dd252788645e940eada959bdde927426e2531c9Paul Duffin public V2 get(Object key) { 14991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V1 value = fromMap.get(key); 15007dd252788645e940eada959bdde927426e2531c9Paul Duffin return (value != null || fromMap.containsKey(key)) ? transformer.transformEntry((K) key, 15017dd252788645e940eada959bdde927426e2531c9Paul Duffin value) : null; 15021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // safe as long as the user followed the <b>Warning</b> in the javadoc 15057dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 15077dd252788645e940eada959bdde927426e2531c9Paul Duffin public V2 remove(Object key) { 15087dd252788645e940eada959bdde927426e2531c9Paul Duffin return fromMap.containsKey(key) ? transformer.transformEntry((K) key, fromMap.remove(key)) 15091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : null; 15101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15127dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15137dd252788645e940eada959bdde927426e2531c9Paul Duffin public void clear() { 15141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fromMap.clear(); 15151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15177dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15187dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<K> keySet() { 15191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap.keySet(); 15201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V2>> entrySet; 15231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15247dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15257dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<Entry<K, V2>> entrySet() { 15261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V2>> result = entrySet; 15271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 15281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet = result = new EntrySet<K, V2>() { 15297dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15307dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, V2> map() { 15311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return TransformedEntriesMap.this; 15321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15347dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15357dd252788645e940eada959bdde927426e2531c9Paul Duffin public Iterator<Entry<K, V2>> iterator() { 15367dd252788645e940eada959bdde927426e2531c9Paul Duffin return new TransformedIterator<Entry<K, V1>, Entry<K, V2>>(fromMap.entrySet() 15377dd252788645e940eada959bdde927426e2531c9Paul Duffin .iterator()) { 15387dd252788645e940eada959bdde927426e2531c9Paul Duffin 15397dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15407dd252788645e940eada959bdde927426e2531c9Paul Duffin Entry<K, V2> transform(final Entry<K, V1> entry) { 15417dd252788645e940eada959bdde927426e2531c9Paul Duffin return new AbstractMapEntry<K, V2>() { 15427dd252788645e940eada959bdde927426e2531c9Paul Duffin 15437dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15447dd252788645e940eada959bdde927426e2531c9Paul Duffin public K getKey() { 15457dd252788645e940eada959bdde927426e2531c9Paul Duffin return entry.getKey(); 15467dd252788645e940eada959bdde927426e2531c9Paul Duffin } 15477dd252788645e940eada959bdde927426e2531c9Paul Duffin 15487dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15497dd252788645e940eada959bdde927426e2531c9Paul Duffin public V2 getValue() { 15507dd252788645e940eada959bdde927426e2531c9Paul Duffin return transformer.transformEntry(entry.getKey(), entry.getValue()); 15511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15527dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 15537dd252788645e940eada959bdde927426e2531c9Paul Duffin } 15547dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 15551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 15571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 15591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V2> values; 15621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15637dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15647dd252788645e940eada959bdde927426e2531c9Paul Duffin public Collection<V2> values() { 15651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V2> result = values; 15661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 15671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values = new Values<K, V2>() { 15687dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15697dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, V2> map() { 15701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return TransformedEntriesMap.this; 15711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 15731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 15751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15787dd252788645e940eada959bdde927426e2531c9Paul Duffin static class TransformedEntriesSortedMap<K, V1, V2> extends TransformedEntriesMap<K, V1, V2> 15797dd252788645e940eada959bdde927426e2531c9Paul Duffin implements SortedMap<K, V2> { 15801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected SortedMap<K, V1> fromMap() { 15821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V1>) fromMap; 15831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TransformedEntriesSortedMap(SortedMap<K, V1> fromMap, 15861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 15871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(fromMap, transformer); 15881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15907dd252788645e940eada959bdde927426e2531c9Paul Duffin public Comparator<? super K> comparator() { 15911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap().comparator(); 15921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15947dd252788645e940eada959bdde927426e2531c9Paul Duffin public K firstKey() { 15951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap().firstKey(); 15961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15987dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V2> headMap(K toKey) { 15991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMap().headMap(toKey), transformer); 16001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16027dd252788645e940eada959bdde927426e2531c9Paul Duffin public K lastKey() { 16031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap().lastKey(); 16041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16067dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V2> subMap(K fromKey, K toKey) { 16077dd252788645e940eada959bdde927426e2531c9Paul Duffin return transformEntries(fromMap().subMap(fromKey, toKey), transformer); 16081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16107dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V2> tailMap(K fromKey) { 16111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMap().tailMap(fromKey), transformer); 16121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16137dd252788645e940eada959bdde927426e2531c9Paul Duffin } 16147dd252788645e940eada959bdde927426e2531c9Paul Duffin 16157dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final class KeyPredicate<K, V> implements Predicate<Entry<K, V>> { 16167dd252788645e940eada959bdde927426e2531c9Paul Duffin private final Predicate<? super K> keyPredicate; 16177dd252788645e940eada959bdde927426e2531c9Paul Duffin 16187dd252788645e940eada959bdde927426e2531c9Paul Duffin KeyPredicate(Predicate<? super K> keyPredicate) { 16197dd252788645e940eada959bdde927426e2531c9Paul Duffin this.keyPredicate = checkNotNull(keyPredicate); 16207dd252788645e940eada959bdde927426e2531c9Paul Duffin } 16217dd252788645e940eada959bdde927426e2531c9Paul Duffin 16227dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean apply(Entry<K, V> input) { 16237dd252788645e940eada959bdde927426e2531c9Paul Duffin return keyPredicate.apply(input.getKey()); 16247dd252788645e940eada959bdde927426e2531c9Paul Duffin } 16257dd252788645e940eada959bdde927426e2531c9Paul Duffin } 16267dd252788645e940eada959bdde927426e2531c9Paul Duffin 16277dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final class ValuePredicate<K, V> implements Predicate<Entry<K, V>> { 16287dd252788645e940eada959bdde927426e2531c9Paul Duffin private final Predicate<? super V> valuePredicate; 16297dd252788645e940eada959bdde927426e2531c9Paul Duffin 16307dd252788645e940eada959bdde927426e2531c9Paul Duffin ValuePredicate(Predicate<? super V> valuePredicate) { 16317dd252788645e940eada959bdde927426e2531c9Paul Duffin this.valuePredicate = checkNotNull(valuePredicate); 16327dd252788645e940eada959bdde927426e2531c9Paul Duffin } 16333c77433663281544363151bf284b0240dfd22a42Paul Duffin 16347dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean apply(Entry<K, V> input) { 16357dd252788645e940eada959bdde927426e2531c9Paul Duffin return valuePredicate.apply(input.getValue()); 16367dd252788645e940eada959bdde927426e2531c9Paul Duffin } 16371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 16401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a map containing the mappings in {@code unfiltered} whose keys 16411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 16421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * changes to one affect the other. 16431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 16451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 16461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a key that 16471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()} 16481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * methods throw an {@link IllegalArgumentException}. 16491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 16511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings whose keys satisfy the 16521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying map. 16531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 16551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 16561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 16581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 16591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 16601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 16611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with 16631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 16641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 16651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 16661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 16677dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> Map<K, V> filterKeys(Map<K, V> unfiltered, 16687dd252788645e940eada959bdde927426e2531c9Paul Duffin final Predicate<? super K> keyPredicate) { 16691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (unfiltered instanceof SortedMap) { 16701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterKeys((SortedMap<K, V>) unfiltered, keyPredicate); 16717dd252788645e940eada959bdde927426e2531c9Paul Duffin } else if (unfiltered instanceof BiMap) { 16727dd252788645e940eada959bdde927426e2531c9Paul Duffin return filterKeys((BiMap<K, V>) unfiltered, keyPredicate); 16731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(keyPredicate); 16757dd252788645e940eada959bdde927426e2531c9Paul Duffin Predicate<Entry<K, V>> entryPredicate = new KeyPredicate<K, V>(keyPredicate); 16767dd252788645e940eada959bdde927426e2531c9Paul Duffin return (unfiltered instanceof AbstractFilteredMap) ? filterFiltered( 16777dd252788645e940eada959bdde927426e2531c9Paul Duffin (AbstractFilteredMap<K, V>) unfiltered, entryPredicate) : new FilteredKeyMap<K, V>( 16787dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(unfiltered), keyPredicate, entryPredicate); 16791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 16821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a sorted map containing the mappings in {@code unfiltered} whose 16831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * keys satisfy a predicate. The returned map is a live view of {@code 16841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered}; changes to one affect the other. 16851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 16871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 16881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a key that 16891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()} 16901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * methods throw an {@link IllegalArgumentException}. 16911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 16931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings whose keys satisfy the 16941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying map. 16951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 16971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 16981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 17001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 17011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 17021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 17031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with 17051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 17061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 17071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 17081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 17101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 17117dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> SortedMap<K, V> filterKeys(SortedMap<K, V> unfiltered, 17127dd252788645e940eada959bdde927426e2531c9Paul Duffin final Predicate<? super K> keyPredicate) { 17137dd252788645e940eada959bdde927426e2531c9Paul Duffin // TODO(user): Return a subclass of Maps.FilteredKeyMap for slightly better 17141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // performance. 17157dd252788645e940eada959bdde927426e2531c9Paul Duffin return filterEntries(unfiltered, new KeyPredicate<K, V>(keyPredicate)); 17167dd252788645e940eada959bdde927426e2531c9Paul Duffin } 17177dd252788645e940eada959bdde927426e2531c9Paul Duffin 17187dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 17197dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a bimap containing the mappings in {@code unfiltered} whose keys satisfy a predicate. 17207dd252788645e940eada959bdde927426e2531c9Paul Duffin * The returned bimap is a live view of {@code unfiltered}; changes to one affect the other. 17217dd252788645e940eada959bdde927426e2531c9Paul Duffin * 17227dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have 17237dd252788645e940eada959bdde927426e2531c9Paul Duffin * iterators that don't support {@code remove()}, but all other methods are supported by the 17247dd252788645e940eada959bdde927426e2531c9Paul Duffin * bimap and its views. When given a key that doesn't satisfy the predicate, the bimap's {@code 17257dd252788645e940eada959bdde927426e2531c9Paul Duffin * put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link 17267dd252788645e940eada959bdde927426e2531c9Paul Duffin * IllegalArgumentException}. 17277dd252788645e940eada959bdde927426e2531c9Paul Duffin * 17287dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered 17297dd252788645e940eada959bdde927426e2531c9Paul Duffin * bimap or its views, only mappings that satisfy the filter will be removed from the underlying 17307dd252788645e940eada959bdde927426e2531c9Paul Duffin * bimap. 17317dd252788645e940eada959bdde927426e2531c9Paul Duffin * 17327dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is. 17337dd252788645e940eada959bdde927426e2531c9Paul Duffin * 17347dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every key in 17357dd252788645e940eada959bdde927426e2531c9Paul Duffin * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i> 17367dd252788645e940eada959bdde927426e2531c9Paul Duffin * needed, it may be faster to copy the filtered bimap and use the copy. 17377dd252788645e940eada959bdde927426e2531c9Paul Duffin * 17387dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as 17397dd252788645e940eada959bdde927426e2531c9Paul Duffin * documented at {@link Predicate#apply}. 17407dd252788645e940eada959bdde927426e2531c9Paul Duffin * 17417dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 14.0 17427dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 17437dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> BiMap<K, V> filterKeys(BiMap<K, V> unfiltered, 17447dd252788645e940eada959bdde927426e2531c9Paul Duffin final Predicate<? super K> keyPredicate) { 17451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(keyPredicate); 17467dd252788645e940eada959bdde927426e2531c9Paul Duffin return filterEntries(unfiltered, new KeyPredicate<K, V>(keyPredicate)); 17471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 17501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a map containing the mappings in {@code unfiltered} whose values 17511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 17521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * changes to one affect the other. 17531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 17551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 17561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a value 17571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that doesn't satisfy the predicate, the map's {@code put()}, {@code 17581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * putAll()}, and {@link Entry#setValue} methods throw an {@link 17591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * IllegalArgumentException}. 17601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 17621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings whose values satisfy the 17631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying map. 17641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 17661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 17671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 17691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 17701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 17711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 17721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 17741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 17751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 17761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 17771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 17787dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> Map<K, V> filterValues(Map<K, V> unfiltered, 17797dd252788645e940eada959bdde927426e2531c9Paul Duffin final Predicate<? super V> valuePredicate) { 17801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (unfiltered instanceof SortedMap) { 17811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterValues((SortedMap<K, V>) unfiltered, valuePredicate); 17827dd252788645e940eada959bdde927426e2531c9Paul Duffin } else if (unfiltered instanceof BiMap) { 17837dd252788645e940eada959bdde927426e2531c9Paul Duffin return filterValues((BiMap<K, V>) unfiltered, valuePredicate); 17841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17857dd252788645e940eada959bdde927426e2531c9Paul Duffin return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate)); 17861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 17891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a sorted map containing the mappings in {@code unfiltered} whose 17901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values satisfy a predicate. The returned map is a live view of {@code 17911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered}; changes to one affect the other. 17921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 17941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 17951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a value 17961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that doesn't satisfy the predicate, the map's {@code put()}, {@code 17971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * putAll()}, and {@link Entry#setValue} methods throw an {@link 17981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * IllegalArgumentException}. 17991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 18011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings whose values satisfy the 18021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying map. 18031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 18051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 18061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 18081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 18091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 18101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 18111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 18131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 18141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 18151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 18161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 18181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 18197dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> SortedMap<K, V> filterValues(SortedMap<K, V> unfiltered, 18207dd252788645e940eada959bdde927426e2531c9Paul Duffin final Predicate<? super V> valuePredicate) { 18217dd252788645e940eada959bdde927426e2531c9Paul Duffin return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate)); 18227dd252788645e940eada959bdde927426e2531c9Paul Duffin } 18237dd252788645e940eada959bdde927426e2531c9Paul Duffin 18247dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 18257dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a bimap containing the mappings in {@code unfiltered} whose values satisfy a 18267dd252788645e940eada959bdde927426e2531c9Paul Duffin * predicate. The returned bimap is a live view of {@code unfiltered}; changes to one affect the 18277dd252788645e940eada959bdde927426e2531c9Paul Duffin * other. 18287dd252788645e940eada959bdde927426e2531c9Paul Duffin * 18297dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have 18307dd252788645e940eada959bdde927426e2531c9Paul Duffin * iterators that don't support {@code remove()}, but all other methods are supported by the 18317dd252788645e940eada959bdde927426e2531c9Paul Duffin * bimap and its views. When given a value that doesn't satisfy the predicate, the bimap's 18327dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link 18337dd252788645e940eada959bdde927426e2531c9Paul Duffin * IllegalArgumentException}. Similarly, the map's entries have a {@link Entry#setValue} method 18347dd252788645e940eada959bdde927426e2531c9Paul Duffin * that throws an {@link IllegalArgumentException} when the provided value doesn't satisfy the 18357dd252788645e940eada959bdde927426e2531c9Paul Duffin * predicate. 18367dd252788645e940eada959bdde927426e2531c9Paul Duffin * 18377dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered 18387dd252788645e940eada959bdde927426e2531c9Paul Duffin * bimap or its views, only mappings that satisfy the filter will be removed from the underlying 18397dd252788645e940eada959bdde927426e2531c9Paul Duffin * bimap. 18407dd252788645e940eada959bdde927426e2531c9Paul Duffin * 18417dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is. 18427dd252788645e940eada959bdde927426e2531c9Paul Duffin * 18437dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every value in 18447dd252788645e940eada959bdde927426e2531c9Paul Duffin * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i> 18457dd252788645e940eada959bdde927426e2531c9Paul Duffin * needed, it may be faster to copy the filtered bimap and use the copy. 18467dd252788645e940eada959bdde927426e2531c9Paul Duffin * 18477dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as 18487dd252788645e940eada959bdde927426e2531c9Paul Duffin * documented at {@link Predicate#apply}. 18497dd252788645e940eada959bdde927426e2531c9Paul Duffin * 18507dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 14.0 18517dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 18527dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> BiMap<K, V> filterValues(BiMap<K, V> unfiltered, 18537dd252788645e940eada959bdde927426e2531c9Paul Duffin final Predicate<? super V> valuePredicate) { 18547dd252788645e940eada959bdde927426e2531c9Paul Duffin return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate)); 18551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 18581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a map containing the mappings in {@code unfiltered} that satisfy a 18591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate. The returned map is a live view of {@code unfiltered}; changes 18601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to one affect the other. 18611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 18631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 18641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a 18651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * key/value pair that doesn't satisfy the predicate, the map's {@code put()} 18661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and {@code putAll()} methods throw an {@link IllegalArgumentException}. 18671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Similarly, the map's entries have a {@link Entry#setValue} method that 18681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * throws an {@link IllegalArgumentException} when the existing key and the 18691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided value don't satisfy the predicate. 18701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 18721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings that satisfy the filter 18731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will be removed from the underlying map. 18741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 18761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 18771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 18791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 18801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 18811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 18821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 18841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. 18851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 18867dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> Map<K, V> filterEntries(Map<K, V> unfiltered, 18877dd252788645e940eada959bdde927426e2531c9Paul Duffin Predicate<? super Entry<K, V>> entryPredicate) { 18881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (unfiltered instanceof SortedMap) { 1889dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return filterEntries((SortedMap<K, V>) unfiltered, entryPredicate); 18907dd252788645e940eada959bdde927426e2531c9Paul Duffin } else if (unfiltered instanceof BiMap) { 18917dd252788645e940eada959bdde927426e2531c9Paul Duffin return filterEntries((BiMap<K, V>) unfiltered, entryPredicate); 1892dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 18933c77433663281544363151bf284b0240dfd22a42Paul Duffin checkNotNull(entryPredicate); 18947dd252788645e940eada959bdde927426e2531c9Paul Duffin return (unfiltered instanceof AbstractFilteredMap) ? filterFiltered( 18957dd252788645e940eada959bdde927426e2531c9Paul Duffin (AbstractFilteredMap<K, V>) unfiltered, entryPredicate) : new FilteredEntryMap<K, V>( 18967dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(unfiltered), entryPredicate); 18971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 19001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a sorted map containing the mappings in {@code unfiltered} that 19011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 19021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * changes to one affect the other. 19031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 19051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 19061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a 19071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * key/value pair that doesn't satisfy the predicate, the map's {@code put()} 19081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and {@code putAll()} methods throw an {@link IllegalArgumentException}. 19091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Similarly, the map's entries have a {@link Entry#setValue} method that 19101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * throws an {@link IllegalArgumentException} when the existing key and the 19111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided value don't satisfy the predicate. 19121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 19141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings that satisfy the filter 19151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will be removed from the underlying map. 19161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 19181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 19191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 19211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 19221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 19231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 19241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 19261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. 19271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1928dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @since 11.0 19291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 19307dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> SortedMap<K, V> filterEntries(SortedMap<K, V> unfiltered, 19311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 19321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entryPredicate); 19337dd252788645e940eada959bdde927426e2531c9Paul Duffin return (unfiltered instanceof FilteredEntrySortedMap) ? filterFiltered( 19347dd252788645e940eada959bdde927426e2531c9Paul Duffin (FilteredEntrySortedMap<K, V>) unfiltered, entryPredicate) 1935dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin : new FilteredEntrySortedMap<K, V>(checkNotNull(unfiltered), entryPredicate); 19361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 19397dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a bimap containing the mappings in {@code unfiltered} that satisfy a predicate. The 19407dd252788645e940eada959bdde927426e2531c9Paul Duffin * returned bimap is a live view of {@code unfiltered}; changes to one affect the other. 19417dd252788645e940eada959bdde927426e2531c9Paul Duffin * 19427dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have 19437dd252788645e940eada959bdde927426e2531c9Paul Duffin * iterators that don't support {@code remove()}, but all other methods are supported by the bimap 19447dd252788645e940eada959bdde927426e2531c9Paul Duffin * and its views. When given a key/value pair that doesn't satisfy the predicate, the bimap's 19457dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an 19467dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@link IllegalArgumentException}. Similarly, the map's entries have an {@link Entry#setValue} 19477dd252788645e940eada959bdde927426e2531c9Paul Duffin * method that throws an {@link IllegalArgumentException} when the existing key and the provided 19487dd252788645e940eada959bdde927426e2531c9Paul Duffin * value don't satisfy the predicate. 19497dd252788645e940eada959bdde927426e2531c9Paul Duffin * 19507dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered 19517dd252788645e940eada959bdde927426e2531c9Paul Duffin * bimap or its views, only mappings that satisfy the filter will be removed from the underlying 19527dd252788645e940eada959bdde927426e2531c9Paul Duffin * bimap. 19537dd252788645e940eada959bdde927426e2531c9Paul Duffin * 19547dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is. 19557dd252788645e940eada959bdde927426e2531c9Paul Duffin * 19567dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every 19577dd252788645e940eada959bdde927426e2531c9Paul Duffin * key/value mapping in the underlying bimap and determine which satisfy the filter. When a live 19587dd252788645e940eada959bdde927426e2531c9Paul Duffin * view is <i>not</i> needed, it may be faster to copy the filtered bimap and use the copy. 19597dd252788645e940eada959bdde927426e2531c9Paul Duffin * 19607dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as 19617dd252788645e940eada959bdde927426e2531c9Paul Duffin * documented at {@link Predicate#apply}. 19627dd252788645e940eada959bdde927426e2531c9Paul Duffin * 19637dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 14.0 19647dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 19657dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> BiMap<K, V> filterEntries(BiMap<K, V> unfiltered, 19667dd252788645e940eada959bdde927426e2531c9Paul Duffin Predicate<? super Entry<K, V>> entryPredicate) { 19677dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(unfiltered); 19687dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(entryPredicate); 19697dd252788645e940eada959bdde927426e2531c9Paul Duffin return (unfiltered instanceof FilteredEntryBiMap) ? filterFiltered( 19707dd252788645e940eada959bdde927426e2531c9Paul Duffin (FilteredEntryBiMap<K, V>) unfiltered, entryPredicate) : new FilteredEntryBiMap<K, V>( 19717dd252788645e940eada959bdde927426e2531c9Paul Duffin unfiltered, entryPredicate); 19727dd252788645e940eada959bdde927426e2531c9Paul Duffin } 19737dd252788645e940eada959bdde927426e2531c9Paul Duffin 19747dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 19751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when 19761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filtering a filtered map. 19771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 19781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Map<K, V> filterFiltered(AbstractFilteredMap<K, V> map, 19791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 19807dd252788645e940eada959bdde927426e2531c9Paul Duffin Predicate<Entry<K, V>> predicate = Predicates.and(map.predicate, entryPredicate); 19811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilteredEntryMap<K, V>(map.unfiltered, predicate); 19821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19847dd252788645e940eada959bdde927426e2531c9Paul Duffin private abstract static class AbstractFilteredMap<K, V> extends AbstractMap<K, V> { 19851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> unfiltered; 19861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Predicate<? super Entry<K, V>> predicate; 19871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19887dd252788645e940eada959bdde927426e2531c9Paul Duffin AbstractFilteredMap(Map<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) { 19891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.unfiltered = unfiltered; 19901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.predicate = predicate; 19911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean apply(Object key, V value) { 19941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // This method is called only when the key is in the map, implying that 19951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // key is a K. 19961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 19971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K k = (K) key; 19981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return predicate.apply(Maps.immutableEntry(k, value)); 19991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20017dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20027dd252788645e940eada959bdde927426e2531c9Paul Duffin public V put(K key, V value) { 20031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(apply(key, value)); 20041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.put(key, value); 20051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20077dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20087dd252788645e940eada959bdde927426e2531c9Paul Duffin public void putAll(Map<? extends K, ? extends V> map) { 20091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<? extends K, ? extends V> entry : map.entrySet()) { 20101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(apply(entry.getKey(), entry.getValue())); 20111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert unfiltered.putAll(map); 20131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20157dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20167dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean containsKey(Object key) { 20171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.containsKey(key) && apply(key, unfiltered.get(key)); 20181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20207dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20217dd252788645e940eada959bdde927426e2531c9Paul Duffin public V get(Object key) { 20221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = unfiltered.get(key); 20231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ((value != null) && apply(key, value)) ? value : null; 20241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20267dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20277dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean isEmpty() { 20281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet().isEmpty(); 20291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20317dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20327dd252788645e940eada959bdde927426e2531c9Paul Duffin public V remove(Object key) { 20331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsKey(key) ? unfiltered.remove(key) : null; 20341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> values; 20371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20387dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20397dd252788645e940eada959bdde927426e2531c9Paul Duffin public Collection<V> values() { 20401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> result = values; 20411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? values = new Values() : result; 20421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class Values extends AbstractCollection<V> { 20457dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20467dd252788645e940eada959bdde927426e2531c9Paul Duffin public Iterator<V> iterator() { 20471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> entryIterator = entrySet().iterator(); 20481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableIterator<V>() { 20497dd252788645e940eada959bdde927426e2531c9Paul Duffin 20501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 20511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator.hasNext(); 20521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V next() { 20551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator.next().getValue(); 20561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 20581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20607dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20617dd252788645e940eada959bdde927426e2531c9Paul Duffin public int size() { 20621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet().size(); 20631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20657dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20667dd252788645e940eada959bdde927426e2531c9Paul Duffin public void clear() { 20671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet().clear(); 20681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20707dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20717dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean isEmpty() { 20721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet().isEmpty(); 20731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20757dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20767dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean remove(Object o) { 20771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 20781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 20791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 20801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) { 20811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 20821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 20831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 20861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20887dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 20897dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean removeAll(Collection<?> collection) { 20901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(collection); 20911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 20921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 20931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 20941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 20951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection.contains(entry.getValue()) && predicate.apply(entry)) { 20961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 20971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 20981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 21011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21037dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 21047dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean retainAll(Collection<?> collection) { 21051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(collection); 21061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 21071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 21081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 21091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 21107dd252788645e940eada959bdde927426e2531c9Paul Duffin if (!collection.contains(entry.getValue()) && predicate.apply(entry)) { 21111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 21121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 21131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 21161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21187dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 21197dd252788645e940eada959bdde927426e2531c9Paul Duffin public Object[] toArray() { 21201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // creating an ArrayList so filtering happens once 21211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Lists.newArrayList(iterator()).toArray(); 21221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21247dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 21257dd252788645e940eada959bdde927426e2531c9Paul Duffin public <T> T[] toArray(T[] array) { 21261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Lists.newArrayList(iterator()).toArray(array); 21271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21307dd252788645e940eada959bdde927426e2531c9Paul Duffin 21311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 21321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when 21331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filtering a filtered sorted map. 21341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 21357dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <K, V> SortedMap<K, V> filterFiltered(FilteredEntrySortedMap<K, V> map, 21361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 21377dd252788645e940eada959bdde927426e2531c9Paul Duffin Predicate<Entry<K, V>> predicate = Predicates.and(map.predicate, entryPredicate); 21381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilteredEntrySortedMap<K, V>(map.sortedMap(), predicate); 21391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21417dd252788645e940eada959bdde927426e2531c9Paul Duffin private static class FilteredEntrySortedMap<K, V> extends FilteredEntryMap<K, V> implements 21427dd252788645e940eada959bdde927426e2531c9Paul Duffin SortedMap<K, V> { 21431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21447dd252788645e940eada959bdde927426e2531c9Paul Duffin FilteredEntrySortedMap(SortedMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 21451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(unfiltered, entryPredicate); 21461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> sortedMap() { 21491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V>) unfiltered; 21501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21527dd252788645e940eada959bdde927426e2531c9Paul Duffin public Comparator<? super K> comparator() { 21531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return sortedMap().comparator(); 21541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21567dd252788645e940eada959bdde927426e2531c9Paul Duffin public K firstKey() { 21571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // correctly throws NoSuchElementException when filtered map is empty. 21581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keySet().iterator().next(); 21591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21617dd252788645e940eada959bdde927426e2531c9Paul Duffin public K lastKey() { 21621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> headMap = sortedMap(); 21631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (true) { 21641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // correctly throws NoSuchElementException when filtered map is empty. 21651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key = headMap.lastKey(); 21661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (apply(key, unfiltered.get(key))) { 21671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return key; 21681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert headMap = sortedMap().headMap(key); 21701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21737dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V> headMap(K toKey) { 21741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilteredEntrySortedMap<K, V>(sortedMap().headMap(toKey), predicate); 21751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21777dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V> subMap(K fromKey, K toKey) { 21787dd252788645e940eada959bdde927426e2531c9Paul Duffin return new FilteredEntrySortedMap<K, V>(sortedMap().subMap(fromKey, toKey), predicate); 21797dd252788645e940eada959bdde927426e2531c9Paul Duffin } 21807dd252788645e940eada959bdde927426e2531c9Paul Duffin 21817dd252788645e940eada959bdde927426e2531c9Paul Duffin public SortedMap<K, V> tailMap(K fromKey) { 21827dd252788645e940eada959bdde927426e2531c9Paul Duffin return new FilteredEntrySortedMap<K, V>(sortedMap().tailMap(fromKey), predicate); 21837dd252788645e940eada959bdde927426e2531c9Paul Duffin } 21847dd252788645e940eada959bdde927426e2531c9Paul Duffin } 21857dd252788645e940eada959bdde927426e2531c9Paul Duffin 21867dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 21877dd252788645e940eada959bdde927426e2531c9Paul Duffin * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when 21887dd252788645e940eada959bdde927426e2531c9Paul Duffin * filtering a filtered map. 21897dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 21907dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <K, V> BiMap<K, V> filterFiltered(FilteredEntryBiMap<K, V> map, 21917dd252788645e940eada959bdde927426e2531c9Paul Duffin Predicate<? super Entry<K, V>> entryPredicate) { 21927dd252788645e940eada959bdde927426e2531c9Paul Duffin Predicate<Entry<K, V>> predicate = Predicates.and(map.predicate, entryPredicate); 21937dd252788645e940eada959bdde927426e2531c9Paul Duffin return new FilteredEntryBiMap<K, V>(map.unfiltered(), predicate); 21947dd252788645e940eada959bdde927426e2531c9Paul Duffin } 21957dd252788645e940eada959bdde927426e2531c9Paul Duffin 21967dd252788645e940eada959bdde927426e2531c9Paul Duffin static final class FilteredEntryBiMap<K, V> extends FilteredEntryMap<K, V> implements BiMap<K, V> { 21977dd252788645e940eada959bdde927426e2531c9Paul Duffin private final BiMap<V, K> inverse; 21987dd252788645e940eada959bdde927426e2531c9Paul Duffin 21997dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <K, V> Predicate<Entry<V, K>> inversePredicate( 22007dd252788645e940eada959bdde927426e2531c9Paul Duffin final Predicate<? super Entry<K, V>> forwardPredicate) { 22017dd252788645e940eada959bdde927426e2531c9Paul Duffin return new Predicate<Entry<V, K>>() { 22027dd252788645e940eada959bdde927426e2531c9Paul Duffin 22037dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean apply(Entry<V, K> input) { 22047dd252788645e940eada959bdde927426e2531c9Paul Duffin return forwardPredicate.apply(Maps.immutableEntry(input.getValue(), input.getKey())); 22057dd252788645e940eada959bdde927426e2531c9Paul Duffin } 22067dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 22077dd252788645e940eada959bdde927426e2531c9Paul Duffin } 22087dd252788645e940eada959bdde927426e2531c9Paul Duffin 22097dd252788645e940eada959bdde927426e2531c9Paul Duffin FilteredEntryBiMap(BiMap<K, V> delegate, Predicate<? super Entry<K, V>> predicate) { 22107dd252788645e940eada959bdde927426e2531c9Paul Duffin super(delegate, predicate); 22117dd252788645e940eada959bdde927426e2531c9Paul Duffin this.inverse = new FilteredEntryBiMap<V, K>(delegate.inverse(), inversePredicate(predicate), 22127dd252788645e940eada959bdde927426e2531c9Paul Duffin this); 22137dd252788645e940eada959bdde927426e2531c9Paul Duffin } 22147dd252788645e940eada959bdde927426e2531c9Paul Duffin 22157dd252788645e940eada959bdde927426e2531c9Paul Duffin private FilteredEntryBiMap(BiMap<K, V> delegate, Predicate<? super Entry<K, V>> predicate, 22167dd252788645e940eada959bdde927426e2531c9Paul Duffin BiMap<V, K> inverse) { 22177dd252788645e940eada959bdde927426e2531c9Paul Duffin super(delegate, predicate); 22187dd252788645e940eada959bdde927426e2531c9Paul Duffin this.inverse = inverse; 22197dd252788645e940eada959bdde927426e2531c9Paul Duffin } 22207dd252788645e940eada959bdde927426e2531c9Paul Duffin 22217dd252788645e940eada959bdde927426e2531c9Paul Duffin BiMap<K, V> unfiltered() { 22227dd252788645e940eada959bdde927426e2531c9Paul Duffin return (BiMap<K, V>) unfiltered; 22231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22257dd252788645e940eada959bdde927426e2531c9Paul Duffin public V forcePut(@Nullable K key, @Nullable V value) { 22267dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(predicate.apply(Maps.immutableEntry(key, value))); 22277dd252788645e940eada959bdde927426e2531c9Paul Duffin return unfiltered().forcePut(key, value); 22287dd252788645e940eada959bdde927426e2531c9Paul Duffin } 22297dd252788645e940eada959bdde927426e2531c9Paul Duffin 22307dd252788645e940eada959bdde927426e2531c9Paul Duffin public BiMap<V, K> inverse() { 22317dd252788645e940eada959bdde927426e2531c9Paul Duffin return inverse; 22327dd252788645e940eada959bdde927426e2531c9Paul Duffin } 22337dd252788645e940eada959bdde927426e2531c9Paul Duffin 22347dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 22357dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<V> values() { 22367dd252788645e940eada959bdde927426e2531c9Paul Duffin return inverse.keySet(); 22371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class FilteredKeyMap<K, V> extends AbstractFilteredMap<K, V> { 22411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super K> keyPredicate; 22421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FilteredKeyMap(Map<K, V> unfiltered, Predicate<? super K> keyPredicate, 22441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> entryPredicate) { 22451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(unfiltered, entryPredicate); 22461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.keyPredicate = keyPredicate; 22471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> entrySet; 22501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22517dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 22527dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<Entry<K, V>> entrySet() { 22531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> result = entrySet; 22547dd252788645e940eada959bdde927426e2531c9Paul Duffin return (result == null) ? entrySet = Sets.filter(unfiltered.entrySet(), predicate) : result; 22551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> keySet; 22581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22597dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 22607dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<K> keySet() { 22611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> result = keySet; 22627dd252788645e940eada959bdde927426e2531c9Paul Duffin return (result == null) ? keySet = Sets.filter(unfiltered.keySet(), keyPredicate) : result; 22631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // The cast is called only when the key is in the unfiltered map, implying 22661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // that key is a K. 22677dd252788645e940eada959bdde927426e2531c9Paul Duffin 22681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 22691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 22701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsKey(Object key) { 22711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.containsKey(key) && keyPredicate.apply((K) key); 22721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class FilteredEntryMap<K, V> extends AbstractFilteredMap<K, V> { 22761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 22771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Entries in this set satisfy the predicate, but they don't validate the 22781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * input to {@code Entry.setValue()}. 22791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 22801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Set<Entry<K, V>> filteredEntrySet; 22811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22827dd252788645e940eada959bdde927426e2531c9Paul Duffin FilteredEntryMap(Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 22831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(unfiltered, entryPredicate); 22841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert filteredEntrySet = Sets.filter(unfiltered.entrySet(), predicate); 22851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> entrySet; 22881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22897dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 22907dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<Entry<K, V>> entrySet() { 22911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> result = entrySet; 22921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? entrySet = new EntrySet() : result; 22931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class EntrySet extends ForwardingSet<Entry<K, V>> { 22967dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 22977dd252788645e940eada959bdde927426e2531c9Paul Duffin protected Set<Entry<K, V>> delegate() { 22981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filteredEntrySet; 22991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23017dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23027dd252788645e940eada959bdde927426e2531c9Paul Duffin public Iterator<Entry<K, V>> iterator() { 23031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator(); 23041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableIterator<Entry<K, V>>() { 23057dd252788645e940eada959bdde927426e2531c9Paul Duffin 23061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 23071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.hasNext(); 23081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Entry<K, V> next() { 23111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Entry<K, V> entry = iterator.next(); 23121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ForwardingMapEntry<K, V>() { 23137dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23147dd252788645e940eada959bdde927426e2531c9Paul Duffin protected Entry<K, V> delegate() { 23151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry; 23161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23187dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23197dd252788645e940eada959bdde927426e2531c9Paul Duffin public V setValue(V value) { 23201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(apply(entry.getKey(), value)); 23211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.setValue(value); 23221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 23241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 23261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> keySet; 23301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23317dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23327dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<K> keySet() { 23331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> result = keySet; 23347dd252788645e940eada959bdde927426e2531c9Paul Duffin return (result == null) ? keySet = createKeySet() : result; 23357dd252788645e940eada959bdde927426e2531c9Paul Duffin } 23367dd252788645e940eada959bdde927426e2531c9Paul Duffin 23377dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<K> createKeySet() { 23387dd252788645e940eada959bdde927426e2531c9Paul Duffin return new KeySet(); 23391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23417dd252788645e940eada959bdde927426e2531c9Paul Duffin private class KeySet extends Sets.ImprovedAbstractSet<K> { 23427dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23437dd252788645e940eada959bdde927426e2531c9Paul Duffin public Iterator<K> iterator() { 23441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator(); 23451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableIterator<K>() { 23467dd252788645e940eada959bdde927426e2531c9Paul Duffin 23471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 23481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.hasNext(); 23491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public K next() { 23521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.next().getKey(); 23531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 23551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23577dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23587dd252788645e940eada959bdde927426e2531c9Paul Duffin public int size() { 23591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filteredEntrySet.size(); 23601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23627dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23637dd252788645e940eada959bdde927426e2531c9Paul Duffin public void clear() { 23641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert filteredEntrySet.clear(); 23651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23677dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23687dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean contains(Object o) { 23691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsKey(o); 23701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23727dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23737dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean remove(Object o) { 23741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (containsKey(o)) { 23751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert unfiltered.remove(o); 23761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 23771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 23791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23817dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23827dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean retainAll(Collection<?> collection) { 23831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(collection); // for GWT 23841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 23851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 23861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 23871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 23887dd252788645e940eada959bdde927426e2531c9Paul Duffin if (predicate.apply(entry) && !collection.contains(entry.getKey())) { 23891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 23901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 23911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2393dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return changed; 2394dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 23953c77433663281544363151bf284b0240dfd22a42Paul Duffin 23967dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 23977dd252788645e940eada959bdde927426e2531c9Paul Duffin public Object[] toArray() { 2398dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin // creating an ArrayList so filtering happens once 2399dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return Lists.newArrayList(iterator()).toArray(); 2400dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 24011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24027dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 24037dd252788645e940eada959bdde927426e2531c9Paul Duffin public <T> T[] toArray(T[] array) { 2404dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return Lists.newArrayList(iterator()).toArray(array); 2405dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 24061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 24101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code AbstractMap} extension that implements {@link #isEmpty()} as {@code 24111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entrySet().isEmpty()} instead of {@code size() == 0} to speed up 24121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implementations where {@code size()} is O(n), and it delegates the {@code 24131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * isEmpty()} methods of its key set and value collection to this 24141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implementation. 24151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 24161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtCompatible 24177dd252788645e940eada959bdde927426e2531c9Paul Duffin abstract static class ImprovedAbstractMap<K, V> extends AbstractMap<K, V> { 24181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 24191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates the entry set to be returned by {@link #entrySet()}. This method 24201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is invoked at most once on a given map, at the time when {@code entrySet} 24211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is first called. 24221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 24231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected abstract Set<Entry<K, V>> createEntrySet(); 24241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Set<Entry<K, V>> entrySet; 24261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24277dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 24287dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<Entry<K, V>> entrySet() { 24291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> result = entrySet; 24301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 24311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet = result = createEntrySet(); 24321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 24341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Set<K> keySet; 24371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24387dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 24397dd252788645e940eada959bdde927426e2531c9Paul Duffin public Set<K> keySet() { 24401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> result = keySet; 24411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 24421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keySet = new KeySet<K, V>() { 24437dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 24447dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, V> map() { 24451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ImprovedAbstractMap.this; 24461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 24481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 24501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Collection<V> values; 24531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24547dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 24557dd252788645e940eada959bdde927426e2531c9Paul Duffin public Collection<V> values() { 24561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> result = values; 24571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 24587dd252788645e940eada959bdde927426e2531c9Paul Duffin return values = new Values<K, V>() { 24597dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 24607dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, V> map() { 24611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ImprovedAbstractMap.this; 24621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 24641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 24661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24697dd252788645e940eada959bdde927426e2531c9Paul Duffin static final MapJoiner STANDARD_JOINER = Collections2.STANDARD_JOINER.withKeyValueSeparator("="); 24701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 24721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Delegates to {@link Map#get}. Returns {@code null} on {@code 24737dd252788645e940eada959bdde927426e2531c9Paul Duffin * ClassCastException} and {@code NullPointerException}. 24741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 24751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <V> V safeGet(Map<?, V> map, Object key) { 24767dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(map); 24771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 24781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.get(key); 24791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ClassCastException e) { 24801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 24817dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (NullPointerException e) { 24827dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 24831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 24871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Delegates to {@link Map#containsKey}. Returns {@code false} on {@code 24887dd252788645e940eada959bdde927426e2531c9Paul Duffin * ClassCastException} and {@code NullPointerException}. 24891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 24901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static boolean safeContainsKey(Map<?, ?> map, Object key) { 24917dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(map); 24921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 24931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.containsKey(key); 24941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ClassCastException e) { 24951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 24967dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (NullPointerException e) { 24977dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 24987dd252788645e940eada959bdde927426e2531c9Paul Duffin } 24997dd252788645e940eada959bdde927426e2531c9Paul Duffin } 25007dd252788645e940eada959bdde927426e2531c9Paul Duffin 25017dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 25027dd252788645e940eada959bdde927426e2531c9Paul Duffin * Delegates to {@link Map#remove}. Returns {@code null} on {@code 25037dd252788645e940eada959bdde927426e2531c9Paul Duffin * ClassCastException} and {@code NullPointerException}. 25047dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 25057dd252788645e940eada959bdde927426e2531c9Paul Duffin static <V> V safeRemove(Map<?, V> map, Object key) { 25067dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(map); 25077dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 25087dd252788645e940eada959bdde927426e2531c9Paul Duffin return map.remove(key); 25097dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (ClassCastException e) { 25107dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 25117dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (NullPointerException e) { 25127dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 25131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Implements {@code Collection.contains} safely for forwarding collections of 25181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map entries. If {@code o} is an instance of {@code Map.Entry}, it is 25191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * wrapped using {@link #unmodifiableEntry} to protect against a possible 25201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * nefarious equals method. 25211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 25221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that {@code c} is the backing (delegate) collection, rather than 25231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the forwarding collection. 25241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 25251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param c the delegate (unwrapped) collection of map entries 25261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param o the object that might be contained in {@code c} 25271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code true} if {@code c} contains {@code o} 25281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> boolean containsEntryImpl(Collection<Entry<K, V>> c, Object o) { 25301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!(o instanceof Entry)) { 25311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 25321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return c.contains(unmodifiableEntry((Entry<?, ?>) o)); 25341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Implements {@code Collection.remove} safely for forwarding collections of 25381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map entries. If {@code o} is an instance of {@code Map.Entry}, it is 25391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * wrapped using {@link #unmodifiableEntry} to protect against a possible 25401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * nefarious equals method. 25411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 25421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that {@code c} is backing (delegate) collection, rather than the 25431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * forwarding collection. 25441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 25451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param c the delegate (unwrapped) collection of map entries 25461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param o the object to remove from {@code c} 25471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code true} if {@code c} was changed 25481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> boolean removeEntryImpl(Collection<Entry<K, V>> c, Object o) { 25501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!(o instanceof Entry)) { 25511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 25521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return c.remove(unmodifiableEntry((Entry<?, ?>) o)); 25541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link Map#equals}. 25581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static boolean equalsImpl(Map<?, ?> map, Object object) { 25601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map == object) { 25611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 25621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object instanceof Map) { 25641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<?, ?> o = (Map<?, ?>) object; 25651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.entrySet().equals(o.entrySet()); 25661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 25681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link Map#toString}. 25721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static String toStringImpl(Map<?, ?> map) { 25747dd252788645e940eada959bdde927426e2531c9Paul Duffin StringBuilder sb = Collections2.newStringBuilderForCollection(map.size()).append('{'); 25751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert STANDARD_JOINER.appendTo(sb, map); 25761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return sb.append('}').toString(); 25771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link Map#putAll}. 25811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25827dd252788645e940eada959bdde927426e2531c9Paul Duffin static <K, V> void putAllImpl(Map<K, V> self, Map<? extends K, ? extends V> map) { 25831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { 25841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert self.put(entry.getKey(), entry.getValue()); 25851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An admittedly inefficient implementation of {@link Map#containsKey}. 25901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static boolean containsKeyImpl(Map<?, ?> map, @Nullable Object key) { 25927dd252788645e940eada959bdde927426e2531c9Paul Duffin return Iterators.contains(keyIterator(map.entrySet().iterator()), key); 25931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link Map#containsValue}. 25971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static boolean containsValueImpl(Map<?, ?> map, @Nullable Object value) { 25997dd252788645e940eada959bdde927426e2531c9Paul Duffin return Iterators.contains(valueIterator(map.entrySet().iterator()), value); 26007dd252788645e940eada959bdde927426e2531c9Paul Duffin } 26017dd252788645e940eada959bdde927426e2531c9Paul Duffin 26027dd252788645e940eada959bdde927426e2531c9Paul Duffin static <K, V> Iterator<K> keyIterator(Iterator<Entry<K, V>> entryIterator) { 26037dd252788645e940eada959bdde927426e2531c9Paul Duffin return new TransformedIterator<Entry<K, V>, K>(entryIterator) { 26047dd252788645e940eada959bdde927426e2531c9Paul Duffin 26057dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 26067dd252788645e940eada959bdde927426e2531c9Paul Duffin K transform(Entry<K, V> entry) { 26077dd252788645e940eada959bdde927426e2531c9Paul Duffin return entry.getKey(); 26081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26097dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 26101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26127dd252788645e940eada959bdde927426e2531c9Paul Duffin abstract static class KeySet<K, V> extends Sets.ImprovedAbstractSet<K> { 26131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Map<K, V> map(); 26141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26157dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 26167dd252788645e940eada959bdde927426e2531c9Paul Duffin public Iterator<K> iterator() { 26177dd252788645e940eada959bdde927426e2531c9Paul Duffin return keyIterator(map().entrySet().iterator()); 26181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26207dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 26217dd252788645e940eada959bdde927426e2531c9Paul Duffin public int size() { 26221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().size(); 26231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26257dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 26267dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean isEmpty() { 26271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().isEmpty(); 26281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26307dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 26317dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean contains(Object o) { 26321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().containsKey(o); 26331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26357dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 26367dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean remove(Object o) { 26371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (contains(o)) { 26381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map().remove(o); 26391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 26401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 26421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26443c77433663281544363151bf284b0240dfd22a42Paul Duffin @Override 26457dd252788645e940eada959bdde927426e2531c9Paul Duffin public void clear() { 2646dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin map().clear(); 26471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26507dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 26517dd252788645e940eada959bdde927426e2531c9Paul Duffin static <K> K keyOrNull(@Nullable Entry<K, ?> entry) { 26527dd252788645e940eada959bdde927426e2531c9Paul Duffin return (entry == null) ? null : entry.getKey(); 26537dd252788645e940eada959bdde927426e2531c9Paul Duffin } 26547dd252788645e940eada959bdde927426e2531c9Paul Duffin 26557dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 26567dd252788645e940eada959bdde927426e2531c9Paul Duffin static <V> V valueOrNull(@Nullable Entry<?, V> entry) { 26577dd252788645e940eada959bdde927426e2531c9Paul Duffin return (entry == null) ? null : entry.getValue(); 26587dd252788645e940eada959bdde927426e2531c9Paul Duffin } 26597dd252788645e940eada959bdde927426e2531c9Paul Duffin 26607dd252788645e940eada959bdde927426e2531c9Paul Duffin static <K, V> Iterator<V> valueIterator(Iterator<Entry<K, V>> entryIterator) { 26617dd252788645e940eada959bdde927426e2531c9Paul Duffin return new TransformedIterator<Entry<K, V>, V>(entryIterator) { 26627dd252788645e940eada959bdde927426e2531c9Paul Duffin 26637dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 26647dd252788645e940eada959bdde927426e2531c9Paul Duffin V transform(Entry<K, V> entry) { 26657dd252788645e940eada959bdde927426e2531c9Paul Duffin return entry.getValue(); 26667dd252788645e940eada959bdde927426e2531c9Paul Duffin } 26677dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 26687dd252788645e940eada959bdde927426e2531c9Paul Duffin } 26697dd252788645e940eada959bdde927426e2531c9Paul Duffin 26707dd252788645e940eada959bdde927426e2531c9Paul Duffin static <K, V> UnmodifiableIterator<V> valueIterator( 26717dd252788645e940eada959bdde927426e2531c9Paul Duffin final UnmodifiableIterator<Entry<K, V>> entryIterator) { 26727dd252788645e940eada959bdde927426e2531c9Paul Duffin return new UnmodifiableIterator<V>() { 26737dd252788645e940eada959bdde927426e2531c9Paul Duffin 26747dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean hasNext() { 26757dd252788645e940eada959bdde927426e2531c9Paul Duffin return entryIterator.hasNext(); 26767dd252788645e940eada959bdde927426e2531c9Paul Duffin } 26777dd252788645e940eada959bdde927426e2531c9Paul Duffin 26787dd252788645e940eada959bdde927426e2531c9Paul Duffin public V next() { 26797dd252788645e940eada959bdde927426e2531c9Paul Duffin return entryIterator.next().getValue(); 26807dd252788645e940eada959bdde927426e2531c9Paul Duffin } 26817dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 26827dd252788645e940eada959bdde927426e2531c9Paul Duffin } 26837dd252788645e940eada959bdde927426e2531c9Paul Duffin 26841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract static class Values<K, V> extends AbstractCollection<V> { 26851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Map<K, V> map(); 26861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26877dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 26887dd252788645e940eada959bdde927426e2531c9Paul Duffin public Iterator<V> iterator() { 26897dd252788645e940eada959bdde927426e2531c9Paul Duffin return valueIterator(map().entrySet().iterator()); 26901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26927dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 26937dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean remove(Object o) { 26941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 26951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.remove(o); 26961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 26971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<K, V> entry : map().entrySet()) { 26981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(o, entry.getValue())) { 26991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map().remove(entry.getKey()); 27001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 27011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 27041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27077dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27087dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean removeAll(Collection<?> c) { 27091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 27101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.removeAll(checkNotNull(c)); 27111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 27121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> toRemove = Sets.newHashSet(); 27131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<K, V> entry : map().entrySet()) { 27141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (c.contains(entry.getValue())) { 27151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert toRemove.add(entry.getKey()); 27161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().keySet().removeAll(toRemove); 27191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27227dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27237dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean retainAll(Collection<?> c) { 27241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 27251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.retainAll(checkNotNull(c)); 27261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 27271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> toRetain = Sets.newHashSet(); 27281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<K, V> entry : map().entrySet()) { 27291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (c.contains(entry.getValue())) { 27301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert toRetain.add(entry.getKey()); 27311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().keySet().retainAll(toRetain); 27341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27377dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27387dd252788645e940eada959bdde927426e2531c9Paul Duffin public int size() { 27391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().size(); 27401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27427dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27437dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean isEmpty() { 27441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().isEmpty(); 27451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27477dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27487dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean contains(@Nullable Object o) { 27491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().containsValue(o); 27501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27527dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27537dd252788645e940eada959bdde927426e2531c9Paul Duffin public void clear() { 27541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map().clear(); 27551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27587dd252788645e940eada959bdde927426e2531c9Paul Duffin abstract static class EntrySet<K, V> extends Sets.ImprovedAbstractSet<Entry<K, V>> { 27591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Map<K, V> map(); 27601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27617dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27627dd252788645e940eada959bdde927426e2531c9Paul Duffin public int size() { 27631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().size(); 27641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27667dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27677dd252788645e940eada959bdde927426e2531c9Paul Duffin public void clear() { 27681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map().clear(); 27691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27717dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27727dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean contains(Object o) { 27731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Entry) { 27741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 27751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = entry.getKey(); 27761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = map().get(key); 27777dd252788645e940eada959bdde927426e2531c9Paul Duffin return Objects.equal(value, entry.getValue()) && (value != null || map().containsKey(key)); 27781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 27801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27827dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27837dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean isEmpty() { 27841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().isEmpty(); 27851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27877dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27887dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean remove(Object o) { 27891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (contains(o)) { 27901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 27911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().keySet().remove(entry.getKey()); 27921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 27941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27967dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 27977dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean removeAll(Collection<?> c) { 27981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 27991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.removeAll(checkNotNull(c)); 28001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 28011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // if the iterators don't support remove 28021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = true; 28031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object o : c) { 28041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed |= remove(o); 28051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 28071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 28107dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 28117dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean retainAll(Collection<?> c) { 28121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 28131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.retainAll(checkNotNull(c)); 28141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 28151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // if the iterators don't support remove 28161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Object> keys = Sets.newHashSetWithExpectedSize(c.size()); 28171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object o : c) { 28181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (contains(o)) { 28191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 28201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keys.add(entry.getKey()); 28211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().keySet().retainAll(keys); 28241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 2828