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.base.Equivalence; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Equivalences; 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.AbstractSet; 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection; 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections; 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator; 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.EnumMap; 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.Set; 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedMap; 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.TreeMap; 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ConcurrentMap; 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Static utility methods pertaining to {@link Map} instances. Also see this 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * class's counterparts {@link Lists} and {@link Sets}. 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kevin Bourrillion 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Isaac Shum 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library) 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true) 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class Maps { 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Maps() {} 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, empty {@code HashMap} instance. 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMap#of()} instead. 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #newEnumMap} instead. 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code HashMap} 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> HashMap<K, V> newHashMap() { 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new HashMap<K, V>(); 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a {@code HashMap} instance, with a high enough "initial capacity" 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that it <i>should</i> hold {@code expectedSize} elements without growth. 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * This behavior cannot be broadly guaranteed, but it is observed to be true 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for OpenJDK 1.6. It also can't be guaranteed that the method isn't 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inadvertently <i>oversizing</i> the returned map. 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param expectedSize the number of elements you expect to add to the 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned map 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code HashMap} with enough capacity to hold {@code 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * expectedSize} elements without resizing 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code expectedSize} is negative 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> HashMap<K, V> newHashMapWithExpectedSize( 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int expectedSize) { 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new HashMap<K, V>(capacity(expectedSize)); 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a capacity that is sufficient to keep the map from being resized as 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * long as it grows no larger than expectedSize and the load factor is >= its 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * default (0.75). 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static int capacity(int expectedSize) { 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (expectedSize < 3) { 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(expectedSize >= 0); 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return expectedSize + 1; 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (expectedSize < Ints.MAX_POWER_OF_TWO) { 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return expectedSize + expectedSize / 3; 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Integer.MAX_VALUE; // any large value 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i> {@code HashMap} instance with the same mappings as 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the specified map. 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMap#copyOf(Map)} instead. 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if {@code K} is an {@link Enum} type, use {@link 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #newEnumMap} instead. 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the mappings to be placed in the new map 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new {@code HashMap} initialized with the mappings from {@code 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map} 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> HashMap<K, V> newHashMap( 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<? extends K, ? extends V> map) { 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new HashMap<K, V>(map); 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, empty, insertion-ordered {@code LinkedHashMap} 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * instance. 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMap#of()} instead. 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code LinkedHashMap} 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() { 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new LinkedHashMap<K, V>(); 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, insertion-ordered {@code LinkedHashMap} instance 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * with the same mappings as the specified map. 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMap#copyOf(Map)} instead. 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the mappings to be placed in the new map 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, {@code LinkedHashMap} initialized with the mappings from 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code map} 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> LinkedHashMap<K, V> newLinkedHashMap( 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<? extends K, ? extends V> map) { 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new LinkedHashMap<K, V>(map); 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a general-purpose instance of {@code ConcurrentMap}, which supports 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * all optional operations of the ConcurrentMap interface. It does not permit 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null keys or values. It is serializable. 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This is currently accomplished by calling {@link MapMaker#makeMap()}. 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It is preferable to use {@code MapMaker} directly (rather than through 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this method), as it presents numerous useful configuration options, 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * such as the concurrency level, load factor, key/value reference types, 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and value computation. 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code ConcurrentMap} 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 3.0 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ConcurrentMap<K, V> newConcurrentMap() { 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new MapMaker().<K, V>makeMap(); 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the natural 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ordering of its elements. 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSortedMap#of()} instead. 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code TreeMap} 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() { 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TreeMap<K, V>(); 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i> {@code TreeMap} instance with the same mappings as 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the specified map and using the same ordering as the specified map. 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@link 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSortedMap#copyOfSorted(SortedMap)} instead. 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the sorted map whose mappings are to be placed in the new map 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and whose comparator is to be used to sort the new map 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new {@code TreeMap} initialized with the mappings from {@code 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map} and using the comparator of {@code map} 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> TreeMap<K, V> newTreeMap(SortedMap<K, ? extends V> map) { 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TreeMap<K, V>(map); 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the given 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * comparator. 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> if mutability is not required, use {@code 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSortedMap.orderedBy(comparator).build()} instead. 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param comparator the comparator to sort the keys with 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code TreeMap} 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <C, K extends C, V> TreeMap<K, V> newTreeMap( 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable Comparator<C> comparator) { 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Ideally, the extra type parameter "C" shouldn't be necessary. It is a 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // work-around of a compiler type inference quirk that prevents the 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // following code from being compiled: 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Comparator<Class<?>> comparator = null; 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Map<Class<? extends Throwable>, String> map = newTreeMap(comparator); 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TreeMap<K, V>(comparator); 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an {@code EnumMap} instance. 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param type the key type for this map 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code EnumMap} 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Class<K> type) { 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EnumMap<K, V>(checkNotNull(type)); 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an {@code EnumMap} with the same mappings as the specified map. 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the map from which to initialize this {@code EnumMap} 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new {@code EnumMap} initialized with the mappings from {@code 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map} 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code m} is not an {@code EnumMap} 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * instance and contains no mappings 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap( 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, ? extends V> map) { 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EnumMap<K, V>(map); 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an {@code IdentityHashMap} instance. 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a new, empty {@code IdentityHashMap} 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() { 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new IdentityHashMap<K, V>(); 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a synchronized (thread-safe) bimap backed by the specified bimap. 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * In order to guarantee serial access, it is critical that <b>all</b> access 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to the backing bimap is accomplished through the returned bimap. 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It is imperative that the user manually synchronize on the returned map 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * when accessing any of its collection views: <pre> {@code 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * BiMap<Long, String> map = Maps.synchronizedBiMap( 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * HashBiMap.<Long, String>create()); 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Set<Long> set = map.keySet(); // Needn't be in synchronized block 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * synchronized (map) { // Synchronizing on map, not set! 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Iterator<Long> it = set.iterator(); // Must be in synchronized block 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * while (it.hasNext()) { 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * foo(it.next()); 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }}</pre> 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Failure to follow this advice may result in non-deterministic behavior. 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned bimap will be serializable if the specified bimap is 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param bimap the bimap to be wrapped in a synchronized view 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a sychronized view of the specified bimap 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) { 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Synchronized.biMap(bimap, null); 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Computes the difference between two maps. This difference is an immutable 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * snapshot of the state of the maps at the time this method is called. It 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will never change, even if the maps change at a later time. 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Since this method uses {@code HashMap} instances internally, the keys of 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the supplied maps must be well-behaved with respect to 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Object#equals} and {@link Object#hashCode}. 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b>If you only need to know whether two maps have the same 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mappings, call {@code left.equals(right)} instead of this method. 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param left the map to treat as the "left" map for purposes of comparison 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param right the map to treat as the "right" map for purposes of comparison 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the difference between the two maps 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> MapDifference<K, V> difference( 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right) { 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (left instanceof SortedMap) { 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, ? extends V> sortedLeft = (SortedMap<K, ? extends V>) left; 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMapDifference<K, V> result = difference(sortedLeft, right); 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return difference(left, right, Equivalences.equals()); 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Computes the difference between two maps. This difference is an immutable 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * snapshot of the state of the maps at the time this method is called. It 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will never change, even if the maps change at a later time. 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Values are compared using a provided equivalence, in the case of 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equality, the value on the 'left' is returned in the difference. 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Since this method uses {@code HashMap} instances internally, the keys of 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the supplied maps must be well-behaved with respect to 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Object#equals} and {@link Object#hashCode}. 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param left the map to treat as the "left" map for purposes of comparison 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param right the map to treat as the "right" map for purposes of comparison 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param valueEquivalence the equivalence relationship to use to compare 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the difference between the two maps 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> MapDifference<K, V> difference( 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right, 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Equivalence<? super V> valueEquivalence) { 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Preconditions.checkNotNull(valueEquivalence); 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> onlyOnLeft = newHashMap(); 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> onlyOnRight = new HashMap<K, V>(right); // will whittle it down 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> onBoth = newHashMap(); 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, MapDifference.ValueDifference<V>> differences = newHashMap(); 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean eq = true; 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<? extends K, ? extends V> entry : left.entrySet()) { 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K leftKey = entry.getKey(); 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V leftValue = entry.getValue(); 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (right.containsKey(leftKey)) { 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V rightValue = onlyOnRight.remove(leftKey); 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (valueEquivalence.equivalent(leftValue, rightValue)) { 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onBoth.put(leftKey, leftValue); 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert eq = false; 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert differences.put( 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert leftKey, ValueDifferenceImpl.create(leftValue, rightValue)); 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert eq = false; 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onlyOnLeft.put(leftKey, leftValue); 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean areEqual = eq && onlyOnRight.isEmpty(); 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return mapDifference( 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert areEqual, onlyOnLeft, onlyOnRight, onBoth, differences); 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> MapDifference<K, V> mapDifference(boolean areEqual, 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> onlyOnLeft, Map<K, V> onlyOnRight, Map<K, V> onBoth, 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, ValueDifference<V>> differences) { 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new MapDifferenceImpl<K, V>(areEqual, 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableMap(onlyOnLeft), 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableMap(onlyOnRight), 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableMap(onBoth), 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableMap(differences)); 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class MapDifferenceImpl<K, V> implements MapDifference<K, V> { 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final boolean areEqual; 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> onlyOnLeft; 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> onlyOnRight; 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> onBoth; 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, ValueDifference<V>> differences; 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapDifferenceImpl(boolean areEqual, Map<K, V> onlyOnLeft, 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> onlyOnRight, Map<K, V> onBoth, 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, ValueDifference<V>> differences) { 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.areEqual = areEqual; 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.onlyOnLeft = onlyOnLeft; 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.onlyOnRight = onlyOnRight; 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.onBoth = onBoth; 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.differences = differences; 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean areEqual() { 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return areEqual; 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, V> entriesOnlyOnLeft() { 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return onlyOnLeft; 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, V> entriesOnlyOnRight() { 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return onlyOnRight; 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, V> entriesInCommon() { 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return onBoth; 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, ValueDifference<V>> entriesDiffering() { 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return differences; 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(Object object) { 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object == this) { 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object instanceof MapDifference) { 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapDifference<?, ?> other = (MapDifference<?, ?>) object; 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entriesOnlyOnLeft().equals(other.entriesOnlyOnLeft()) 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && entriesOnlyOnRight().equals(other.entriesOnlyOnRight()) 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && entriesInCommon().equals(other.entriesInCommon()) 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && entriesDiffering().equals(other.entriesDiffering()); 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Objects.hashCode(entriesOnlyOnLeft(), entriesOnlyOnRight(), 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entriesInCommon(), entriesDiffering()); 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String toString() { 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (areEqual) { 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return "equal"; 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert StringBuilder result = new StringBuilder("not equal"); 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!onlyOnLeft.isEmpty()) { 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.append(": only on left=").append(onlyOnLeft); 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!onlyOnRight.isEmpty()) { 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.append(": only on right=").append(onlyOnRight); 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!differences.isEmpty()) { 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.append(": value differences=").append(differences); 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result.toString(); 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class ValueDifferenceImpl<V> 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert implements MapDifference.ValueDifference<V> { 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final V left; 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final V right; 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <V> ValueDifference<V> create(@Nullable V left, @Nullable V right) { 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ValueDifferenceImpl<V>(left, right); 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ValueDifferenceImpl(@Nullable V left, @Nullable V right) { 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.left = left; 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.right = right; 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V leftValue() { 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return left; 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V rightValue() { 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return right; 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object object) { 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object instanceof MapDifference.ValueDifference<?>) { 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapDifference.ValueDifference<?> that = 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert (MapDifference.ValueDifference<?>) object; 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Objects.equal(this.left, that.leftValue()) 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && Objects.equal(this.right, that.rightValue()); 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Objects.hashCode(left, right); 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String toString() { 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return "(" + left + ", " + right + ")"; 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Computes the difference between two sorted maps, using the comparator of 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the left map, or {@code Ordering.natural()} if the left map uses the 5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * natural ordering of its elements. This difference is an immutable snapshot 5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of the state of the maps at the time this method is called. It will never 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * change, even if the maps change at a later time. 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Since this method uses {@code TreeMap} instances internally, the keys of 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the right map must all compare as distinct according to the comparator 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of the left map. 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b>If you only need to know whether two sorted maps have the 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * same mappings, call {@code left.equals(right)} instead of this method. 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param left the map to treat as the "left" map for purposes of comparison 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param right the map to treat as the "right" map for purposes of comparison 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the difference between the two maps 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedMapDifference<K, V> difference( 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right) { 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(left); 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(right); 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Comparator<? super K> comparator = orNaturalOrder(left.comparator()); 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> onlyOnLeft = Maps.newTreeMap(comparator); 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> onlyOnRight = Maps.newTreeMap(comparator); 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onlyOnRight.putAll(right); // will whittle it down 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> onBoth = Maps.newTreeMap(comparator); 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, MapDifference.ValueDifference<V>> differences = 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Maps.newTreeMap(comparator); 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean eq = true; 5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<? extends K, ? extends V> entry : left.entrySet()) { 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K leftKey = entry.getKey(); 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V leftValue = entry.getValue(); 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (right.containsKey(leftKey)) { 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V rightValue = onlyOnRight.remove(leftKey); 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(leftValue, rightValue)) { 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onBoth.put(leftKey, leftValue); 5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert eq = false; 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert differences.put( 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert leftKey, ValueDifferenceImpl.create(leftValue, rightValue)); 5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert eq = false; 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert onlyOnLeft.put(leftKey, leftValue); 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean areEqual = eq && onlyOnRight.isEmpty(); 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return sortedMapDifference( 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert areEqual, onlyOnLeft, onlyOnRight, onBoth, differences); 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> SortedMapDifference<K, V> sortedMapDifference( 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean areEqual, SortedMap<K, V> onlyOnLeft, SortedMap<K, V> onlyOnRight, 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> onBoth, SortedMap<K, ValueDifference<V>> differences) { 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new SortedMapDifferenceImpl<K, V>(areEqual, 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableSortedMap(onlyOnLeft), 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableSortedMap(onlyOnRight), 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableSortedMap(onBoth), 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableSortedMap(differences)); 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class SortedMapDifferenceImpl<K, V> extends MapDifferenceImpl<K, V> 5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert implements SortedMapDifference<K, V> { 5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMapDifferenceImpl(boolean areEqual, SortedMap<K, V> onlyOnLeft, 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> onlyOnRight, SortedMap<K, V> onBoth, 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, ValueDifference<V>> differences) { 5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(areEqual, onlyOnLeft, onlyOnRight, onBoth, differences); 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, ValueDifference<V>> entriesDiffering() { 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, ValueDifference<V>>) super.entriesDiffering(); 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, V> entriesInCommon() { 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V>) super.entriesInCommon(); 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, V> entriesOnlyOnLeft() { 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V>) super.entriesOnlyOnLeft(); 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, V> entriesOnlyOnRight() { 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V>) super.entriesOnlyOnRight(); 6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the specified comparator if not null; otherwise returns {@code 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Ordering.natural()}. This method is an abomination of generics; the only 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * purpose of this method is to contain the ugly type-casting in one place. 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <E> Comparator<? super E> orNaturalOrder( 6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable Comparator<? super E> comparator) { 6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (comparator != null) { // can't use ? : because of javac bug 5080917 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return comparator; 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (Comparator<E>) Ordering.natural(); 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable map for which the {@link Map#values} are the given 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * elements in the given order, and each key is the product of invoking a 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * supplied function on its corresponding value. 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param values the values to use when constructing the {@code Map} 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param keyFunction the function used to produce the key for each value 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a map mapping the result of evaluating the function {@code 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * keyFunction} on each value in the input collection to that value 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code keyFunction} produces the same 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * key for more than one value in the input collection 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any elements of {@code values} is null, or 6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * if {@code keyFunction} produces {@code null} for any value 6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ImmutableMap<K, V> uniqueIndex( 6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterable<V> values, Function<? super V, K> keyFunction) { 6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return uniqueIndex(values.iterator(), keyFunction); 6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <b>Deprecated.</b> 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated use {@link #uniqueIndex(Iterator, Function)} by casting {@code 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values} to {@code Iterator<V>}, or better yet, by implementing only 6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled 6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for deletion in March 2012.</b> 6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated 6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V, I extends Object & Iterable<V> & Iterator<V>> 6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableMap<K, V> uniqueIndex( 6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert I values, Function<? super V, K> keyFunction) { 6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterable<V> valuesIterable = checkNotNull(values); 6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return uniqueIndex(valuesIterable, keyFunction); 6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable map for which the {@link Map#values} are the given 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * elements in the given order, and each key is the product of invoking a 6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * supplied function on its corresponding value. 6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param values the values to use when constructing the {@code Map} 6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param keyFunction the function used to produce the key for each value 6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a map mapping the result of evaluating the function {@code 6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * keyFunction} on each value in the input collection to that value 6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code keyFunction} produces the same 6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * key for more than one value in the input collection 6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any elements of {@code values} is null, or 6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * if {@code keyFunction} produces {@code null} for any value 6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ImmutableMap<K, V> uniqueIndex( 6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<V> values, Function<? super V, K> keyFunction) { 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(keyFunction); 6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableMap.Builder<K, V> builder = ImmutableMap.builder(); 6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (values.hasNext()) { 6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = values.next(); 6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.put(keyFunction.apply(value), value); 6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return builder.build(); 6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable map entry with the specified key and value. The {@link 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned entry is serializable. 6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param key the key to be associated with the returned entry 6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param value the value to be associated with the returned entry 6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtCompatible(serializable = true) 6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Entry<K, V> immutableEntry( 6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable K key, @Nullable V value) { 6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ImmutableEntry<K, V>(key, value); 6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified set of entries. The {@link 6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Entry#setValue} operation throws an {@link UnsupportedOperationException}, 6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * as do any operations that would modify the returned set. 7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entrySet the entries for which to return an unmodifiable view 7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the entries 7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> Set<Entry<K, V>> unmodifiableEntrySet( 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> entrySet) { 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableEntrySet<K, V>( 7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableSet(entrySet)); 7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified map entry. The {@link 7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * This also has the side-effect of redefining {@code equals} to comply with 7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the Entry contract, to avoid a possible nefarious implementation of equals. 7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entry the entry for which to return an unmodifiable view 7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the entry 7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> Entry<K, V> unmodifiableEntry(final Entry<K, V> entry) { 7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entry); 7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractMapEntry<K, V>() { 7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K getKey() { 7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getKey(); 7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V getValue() { 7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getValue(); 7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see Multimaps#unmodifiableEntries */ 7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class UnmodifiableEntries<K, V> 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingCollection<Entry<K, V>> { 7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final Collection<Entry<K, V>> entries; 7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableEntries(Collection<Entry<K, V>> entries) { 7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.entries = entries; 7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Collection<Entry<K, V>> delegate() { 7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entries; 7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<K, V>> iterator() { 7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> delegate = super.iterator(); 7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ForwardingIterator<Entry<K, V>>() { 7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Entry<K, V> next() { 7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unmodifiableEntry(super.next()); 7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void remove() { 7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Iterator<Entry<K, V>> delegate() { 7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // See java.util.Collections.UnmodifiableEntrySet for details on attacks. 7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean add(Entry<K, V> element) { 7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean addAll( 7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<? extends Entry<K, V>> collection) { 7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object object) { 7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> collection) { 7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> collection) { 7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Object[] toArray() { 7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(); 7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public <T> T[] toArray(T[] array) { 7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(array); 7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see Maps#unmodifiableEntrySet(Set) */ 7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class UnmodifiableEntrySet<K, V> 8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends UnmodifiableEntries<K, V> implements Set<Entry<K, V>> { 8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableEntrySet(Set<Entry<K, V>> entries) { 8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(entries); 8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // See java.util.Collections.UnmodifiableEntrySet for details on attacks. 8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object object) { 8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.equalsImpl(this, object); 8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.hashCodeImpl(this); 8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified bimap. This method allows 8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modules to provide users with "read-only" access to internal bimaps. Query 8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * operations on the returned bimap "read through" to the specified bimap, and 8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * attempts to modify the returned map, whether direct or via its collection 8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * views, result in an {@code UnsupportedOperationException}. 8221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned bimap will be serializable if the specified bimap is 8241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param bimap the bimap for which an unmodifiable view is to be returned 8271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified bimap 8281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> BiMap<K, V> unmodifiableBiMap( 8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BiMap<? extends K, ? extends V> bimap) { 8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableBiMap<K, V>(bimap, null); 8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see Maps#unmodifiableBiMap(BiMap) */ 8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class UnmodifiableBiMap<K, V> 8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingMap<K, V> implements BiMap<K, V>, Serializable { 8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> unmodifiableMap; 8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final BiMap<? extends K, ? extends V> delegate; 8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient BiMap<V, K> inverse; 8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Set<V> values; 8411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate, 8431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable BiMap<V, K> inverse) { 8441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert unmodifiableMap = Collections.unmodifiableMap(delegate); 8451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = delegate; 8461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.inverse = inverse; 8471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Map<K, V> delegate() { 8501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unmodifiableMap; 8511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 8541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V forcePut(K key, V value) { 8551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 8561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 8591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public BiMap<V, K> inverse() { 8601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BiMap<V, K> result = inverse; 8611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) 8621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? inverse = new UnmodifiableBiMap<V, K>(delegate.inverse(), this) 8631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : result; 8641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<V> values() { 8671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<V> result = values; 8681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) 8691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? values = Collections.unmodifiableSet(delegate.values()) 8701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : result; 8711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 8741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a map where each value is transformed by a function. All 8781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other properties of the map, such as iteration order, are left intact. For 8791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * example, the code: <pre> {@code 8801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9); 8821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<Integer, Double> sqrt = 8831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new Function<Integer, Double>() { 8841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public Double apply(Integer in) { 8851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return Math.sqrt((int) in); 8861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 8871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 8881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map<String, Double> transformed = Maps.transformValues(map, sqrt); 8891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 8901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {a=2.0, b=3.0}}. 8921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying map are reflected in this view. Conversely, 8941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this view supports removal operations, and these are reflected in the 8951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map. 8961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying map to contain null keys, and even 8981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null values provided that the function is capable of accepting null input. 8991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The transformed map might contain null values, if the function sometimes 9001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * gives a null result. 9011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map is not thread-safe or serializable, even if the 9031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map is. 9041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The function is applied lazily, invoked when needed. This is necessary 9061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for the returned map to be a view, but it means that the function will be 9071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * applied many times for bulk operations like {@link Map#containsValue} and 9081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Map.toString()}. For this to perform well, {@code function} should 9091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be fast. To avoid lazy evaluation when the returned map doesn't need to be 9101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a view, copy the returned map into a new map of your choosing. 9111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 9121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V1, V2> Map<K, V2> transformValues( 9131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V1> fromMap, final Function<? super V1, V2> function) { 9141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(function); 9151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<K, V1, V2> transformer = 9161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new EntryTransformer<K, V1, V2>() { 9171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 9181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V2 transformEntry(K key, V1 value) { 9191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return function.apply(value); 9201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 9221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMap, transformer); 9231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 9261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a sorted map where each value is transformed by a 9271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function. All other properties of the map, such as iteration order, are 9281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * left intact. For example, the code: <pre> {@code 9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9); 9311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<Integer, Double> sqrt = 9321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new Function<Integer, Double>() { 9331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public Double apply(Integer in) { 9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return Math.sqrt((int) in); 9351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 9361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 9371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * SortedMap<String, Double> transformed = 9381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Maps.transformSortedValues(map, sqrt); 9391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 9401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {a=2.0, b=3.0}}. 9421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying map are reflected in this view. Conversely, 9441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this view supports removal operations, and these are reflected in the 9451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map. 9461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying map to contain null keys, and even 9481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null values provided that the function is capable of accepting null input. 9491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The transformed map might contain null values, if the function sometimes 9501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * gives a null result. 9511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map is not thread-safe or serializable, even if the 9531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map is. 9541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The function is applied lazily, invoked when needed. This is necessary 9561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for the returned map to be a view, but it means that the function will be 9571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * applied many times for bulk operations like {@link Map#containsValue} and 9581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Map.toString()}. For this to perform well, {@code function} should 9591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be fast. To avoid lazy evaluation when the returned map doesn't need to be 9601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a view, copy the returned map into a new map of your choosing. 9611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 9631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 9641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 9651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V1, V2> SortedMap<K, V2> transformValues( 9661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V1> fromMap, final Function<? super V1, V2> function) { 9671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(function); 9681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<K, V1, V2> transformer = 9691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new EntryTransformer<K, V1, V2>() { 9701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 9711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V2 transformEntry(K key, V1 value) { 9721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return function.apply(value); 9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 9751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMap, transformer); 9761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 9791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a map whose values are derived from the original map's 9801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entries. In contrast to {@link #transformValues}, this method's 9811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entry-transformation logic may depend on the key as well as the value. 9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>All other properties of the transformed map, such as iteration order, 9841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * are left intact. For example, the code: <pre> {@code 9851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map<String, Boolean> options = 9871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMap.of("verbose", true, "sort", false); 9881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer<String, Boolean, String> flagPrefixer = 9891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new EntryTransformer<String, Boolean, String>() { 9901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public String transformEntry(String key, Boolean value) { 9911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return value ? key : "no" + key; 9921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 9931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 9941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map<String, String> transformed = 9951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Maps.transformEntries(options, flagPrefixer); 9961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 9971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {verbose=verbose, sort=nosort}}. 9991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying map are reflected in this view. Conversely, 10011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this view supports removal operations, and these are reflected in the 10021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map. 10031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying map to contain null keys and null 10051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values provided that the transformer is capable of accepting null inputs. 10061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The transformed map might contain null values if the transformer sometimes 10071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * gives a null result. 10081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map is not thread-safe or serializable, even if the 10101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map is. 10111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The transformer is applied lazily, invoked when needed. This is 10131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * necessary for the returned map to be a view, but it means that the 10141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer will be applied many times for bulk operations like {@link 10151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map#containsValue} and {@link Object#toString}. For this to perform well, 10161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code transformer} should be fast. To avoid lazy evaluation when the 10171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned map doesn't need to be a view, copy the returned map into a new 10181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map of your choosing. 10191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 10221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that {@code k2} is also of type {@code K}. Using an {@code 10231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer} key type for which this may not hold, such as {@code 10241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ArrayList}, may risk a {@code ClassCastException} when calling methods on 10251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the transformed map. 10261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 10281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 10291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V1, V2> Map<K, V2> transformEntries( 10301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V1> fromMap, 10311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 10321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (fromMap instanceof SortedMap) { 10331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries((SortedMap<K, V1>) fromMap, transformer); 10341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TransformedEntriesMap<K, V1, V2>(fromMap, transformer); 10361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 10391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a sorted map whose values are derived from the original 10401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sorted map's entries. In contrast to {@link #transformValues}, this 10411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * method's entry-transformation logic may depend on the key as well as the 10421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * value. 10431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>All other properties of the transformed map, such as iteration order, 10451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * are left intact. For example, the code: <pre> {@code 10461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map<String, Boolean> options = 10481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSortedMap.of("verbose", true, "sort", false); 10491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer<String, Boolean, String> flagPrefixer = 10501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new EntryTransformer<String, Boolean, String>() { 10511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public String transformEntry(String key, Boolean value) { 10521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return value ? key : "yes" + key; 10531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 10541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 10551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * SortedMap<String, String> transformed = 10561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * LabsMaps.transformSortedEntries(options, flagPrefixer); 10571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 10581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {sort=yessort, verbose=verbose}}. 10601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying map are reflected in this view. Conversely, 10621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this view supports removal operations, and these are reflected in the 10631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map. 10641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying map to contain null keys and null 10661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values provided that the transformer is capable of accepting null inputs. 10671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The transformed map might contain null values if the transformer sometimes 10681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * gives a null result. 10691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map is not thread-safe or serializable, even if the 10711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying map is. 10721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The transformer is applied lazily, invoked when needed. This is 10741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * necessary for the returned map to be a view, but it means that the 10751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer will be applied many times for bulk operations like {@link 10761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Map#containsValue} and {@link Object#toString}. For this to perform well, 10771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code transformer} should be fast. To avoid lazy evaluation when the 10781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned map doesn't need to be a view, copy the returned map into a new 10791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map of your choosing. 10801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 10821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 10831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that {@code k2} is also of type {@code K}. Using an {@code 10841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer} key type for which this may not hold, such as {@code 10851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ArrayList}, may risk a {@code ClassCastException} when calling methods on 10861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the transformed map. 10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 10891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 10901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 10911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V1, V2> SortedMap<K, V2> transformEntries( 10921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final SortedMap<K, V1> fromMap, 10931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 10941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TransformedEntriesSortedMap<K, V1, V2>(fromMap, transformer); 10951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 10981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A transformation of the value of a key-value pair, using both key and value 10991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * as inputs. To apply the transformation to a map, use 11001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Maps#transformEntries(Map, EntryTransformer)}. 11011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param <K> the key type of the input and output entries 11031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @paramthe value type of the input entry 11041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param the value type of the output entry 11051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 11061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 11071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public interface EntryTransformer<K, V1, V2> { 11081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 11091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Determines an output value based on a key-value pair. This method is 11101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <i>generally expected</i>, but not absolutely required, to have the 11111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * following properties: 11121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <ul> 11141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>Its execution does not cause any observable side effects. 11151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>The computation is <i>consistent with equals</i>; that is, 11161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Objects#equal Objects.equal}{@code (k1, k2) &&} 11171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Objects#equal}{@code (v1, v2)} implies that {@code 11181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Objects.equal(transformer.transform(k1, v1), 11191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer.transform(k2, v2))}. 11201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * </ul> 11211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if the key or value is null and this 11231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer does not accept null arguments 11241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 11251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V2 transformEntry(@Nullable K key, @Nullable V1 value); 11261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class TransformedEntriesMap<K, V1, V2> 11291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends AbstractMap<K, V2> { 11301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V1> fromMap; 11311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final EntryTransformer<? super K, ? super V1, V2> transformer; 11321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TransformedEntriesMap( 11341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V1> fromMap, 11351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 11361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.fromMap = checkNotNull(fromMap); 11371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.transformer = checkNotNull(transformer); 11381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 11411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap.size(); 11421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object key) { 11451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap.containsKey(key); 11461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // safe as long as the user followed the <b>Warning</b> in the javadoc 11491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 11501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V2 get(Object key) { 11511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V1 value = fromMap.get(key); 11521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (value != null || fromMap.containsKey(key)) 11531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? transformer.transformEntry((K) key, value) 11541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : null; 11551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // safe as long as the user followed the <b>Warning</b> in the javadoc 11581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 11591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V2 remove(Object key) { 11601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap.containsKey(key) 11611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? transformer.transformEntry((K) key, fromMap.remove(key)) 11621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : null; 11631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 11661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fromMap.clear(); 11671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> keySet() { 11701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap.keySet(); 11711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V2>> entrySet; 11741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<K, V2>> entrySet() { 11761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V2>> result = entrySet; 11771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 11781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet = result = new EntrySet<K, V2>() { 11791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Map<K, V2> map() { 11801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return TransformedEntriesMap.this; 11811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<K, V2>> iterator() { 11841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V1>> backingIterator = 11851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fromMap.entrySet().iterator(); 11861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Iterators.transform(backingIterator, 11871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Function<Entry<K, V1>, Entry<K, V2>>() { 11881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Entry<K, V2> apply(Entry<K, V1> entry) { 11891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return immutableEntry( 11901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.getKey(), 11911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transformer.transformEntry(entry.getKey(), 11921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.getValue())); 11931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 11951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 11971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 11991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V2> values; 12021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V2> values() { 12041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V2> result = values; 12051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 12061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values = new Values<K, V2>() { 12071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Map<K, V2> map() { 12081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return TransformedEntriesMap.this; 12091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 12111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 12131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class TransformedEntriesSortedMap<K, V1, V2> 12171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends TransformedEntriesMap<K, V1, V2> implements SortedMap<K, V2> { 12181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected SortedMap<K, V1> fromMap() { 12201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V1>) fromMap; 12211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TransformedEntriesSortedMap(SortedMap<K, V1> fromMap, 12241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 12251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(fromMap, transformer); 12261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Comparator<? super K> comparator() { 12291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap().comparator(); 12301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K firstKey() { 12331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap().firstKey(); 12341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, V2> headMap(K toKey) { 12371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMap().headMap(toKey), transformer); 12381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K lastKey() { 12411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMap().lastKey(); 12421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, V2> subMap(K fromKey, K toKey) { 12451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries( 12461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fromMap().subMap(fromKey, toKey), transformer); 12471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, V2> tailMap(K fromKey) { 12501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMap().tailMap(fromKey), transformer); 12511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 12561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a map containing the mappings in {@code unfiltered} whose keys 12571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 12581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * changes to one affect the other. 12591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 12611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 12621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a key that 12631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()} 12641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * methods throw an {@link IllegalArgumentException}. 12651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 12671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings whose keys satisfy the 12681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying map. 12691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 12711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 12721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 12741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 12751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 12761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 12771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with 12791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 12801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 12811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 12821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 12831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Map<K, V> filterKeys( 12841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 12851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (unfiltered instanceof SortedMap) { 12861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterKeys((SortedMap<K, V>) unfiltered, keyPredicate); 12871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(keyPredicate); 12891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> entryPredicate = 12901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Predicate<Entry<K, V>>() { 12911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 12921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean apply(Entry<K, V> input) { 12931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keyPredicate.apply(input.getKey()); 12941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 12961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (unfiltered instanceof AbstractFilteredMap) 12971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate) 12981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : new FilteredKeyMap<K, V>( 12991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(unfiltered), keyPredicate, entryPredicate); 13001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 13031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a sorted map containing the mappings in {@code unfiltered} whose 13041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * keys satisfy a predicate. The returned map is a live view of {@code 13051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered}; changes to one affect the other. 13061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 13081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 13091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a key that 13101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()} 13111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * methods throw an {@link IllegalArgumentException}. 13121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 13141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings whose keys satisfy the 13151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying map. 13161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 13181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 13191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 13211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 13221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 13231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 13241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with 13261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 13271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 13281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 13291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 13311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 13321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 13331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedMap<K, V> filterKeys( 13341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 13351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO: Return a subclass of Maps.FilteredKeyMap for slightly better 13361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // performance. 13371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(keyPredicate); 13381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> entryPredicate = new Predicate<Entry<K, V>>() { 13391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 13401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean apply(Entry<K, V> input) { 13411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keyPredicate.apply(input.getKey()); 13421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 13441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterEntries(unfiltered, entryPredicate); 13451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 13481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a map containing the mappings in {@code unfiltered} whose values 13491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 13501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * changes to one affect the other. 13511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 13531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 13541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a value 13551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that doesn't satisfy the predicate, the map's {@code put()}, {@code 13561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * putAll()}, and {@link Entry#setValue} methods throw an {@link 13571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * IllegalArgumentException}. 13581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 13601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings whose values satisfy the 13611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying map. 13621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 13641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 13651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 13671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 13681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 13691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 13701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 13721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 13731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 13741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 13751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 13761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Map<K, V> filterValues( 13771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 13781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (unfiltered instanceof SortedMap) { 13791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterValues((SortedMap<K, V>) unfiltered, valuePredicate); 13801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(valuePredicate); 13821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> entryPredicate = 13831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Predicate<Entry<K, V>>() { 13841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 13851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean apply(Entry<K, V> input) { 13861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return valuePredicate.apply(input.getValue()); 13871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 13891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterEntries(unfiltered, entryPredicate); 13901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 13931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a sorted map containing the mappings in {@code unfiltered} whose 13941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values satisfy a predicate. The returned map is a live view of {@code 13951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered}; changes to one affect the other. 13961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 13981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 13991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a value 14001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that doesn't satisfy the predicate, the map's {@code put()}, {@code 14011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * putAll()}, and {@link Entry#setValue} methods throw an {@link 14021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * IllegalArgumentException}. 14031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 14051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings whose values satisfy the 14061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying map. 14071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 14091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 14101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 14121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 14131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 14141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 14151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 14171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 14181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 14191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 14201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 14221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 14231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 14241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedMap<K, V> filterValues( 14251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 14261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(valuePredicate); 14271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> entryPredicate = 14281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Predicate<Entry<K, V>>() { 14291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 14301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean apply(Entry<K, V> input) { 14311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return valuePredicate.apply(input.getValue()); 14321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 14341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterEntries(unfiltered, entryPredicate); 14351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 14381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a map containing the mappings in {@code unfiltered} that satisfy a 14391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate. The returned map is a live view of {@code unfiltered}; changes 14401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to one affect the other. 14411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 14431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 14441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a 14451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * key/value pair that doesn't satisfy the predicate, the map's {@code put()} 14461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and {@code putAll()} methods throw an {@link IllegalArgumentException}. 14471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Similarly, the map's entries have a {@link Entry#setValue} method that 14481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * throws an {@link IllegalArgumentException} when the existing key and the 14491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided value don't satisfy the predicate. 14501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 14521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings that satisfy the filter 14531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will be removed from the underlying map. 14541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 14561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 14571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 14591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 14601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 14611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 14621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 14641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. 14651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 14661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Map<K, V> filterEntries( 14671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 14681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (unfiltered instanceof SortedMap) { 14691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterEntries((SortedMap<K, V>) unfiltered, entryPredicate); 14701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entryPredicate); 14721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (unfiltered instanceof AbstractFilteredMap) 14731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate) 14741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : new FilteredEntryMap<K, V>(checkNotNull(unfiltered), entryPredicate); 14751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 14781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a sorted map containing the mappings in {@code unfiltered} that 14791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 14801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * changes to one affect the other. 14811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 14831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values()} views have iterators that don't support {@code remove()}, but all 14841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * other methods are supported by the map and its views. When given a 14851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * key/value pair that doesn't satisfy the predicate, the map's {@code put()} 14861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and {@code putAll()} methods throw an {@link IllegalArgumentException}. 14871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Similarly, the map's entries have a {@link Entry#setValue} method that 14881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * throws an {@link IllegalArgumentException} when the existing key and the 14891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided value don't satisfy the predicate. 14901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called 14921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the filtered map or its views, only mappings that satisfy the filter 14931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will be removed from the underlying map. 14941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map isn't threadsafe or serializable, even if {@code 14961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unfiltered} is. 14971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered map's methods, such as {@code size()}, 14991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterate across every key/value mapping in the underlying map and determine 15001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 15011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered map and use the copy. 15021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 15031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 15041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. 15051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 15061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 15071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 15081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 15091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedMap<K, V> filterEntries( 15101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> unfiltered, 15111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 15121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entryPredicate); 15131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (unfiltered instanceof FilteredEntrySortedMap) 15141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? filterFiltered((FilteredEntrySortedMap<K, V>) unfiltered, entryPredicate) 15151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : new FilteredEntrySortedMap<K, V>(checkNotNull(unfiltered), entryPredicate); 15161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 15191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when 15201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filtering a filtered map. 15211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 15221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Map<K, V> filterFiltered(AbstractFilteredMap<K, V> map, 15231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 15241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> predicate = 15251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicates.and(map.predicate, entryPredicate); 15261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilteredEntryMap<K, V>(map.unfiltered, predicate); 15271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private abstract static class AbstractFilteredMap<K, V> 15301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends AbstractMap<K, V> { 15311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> unfiltered; 15321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Predicate<? super Entry<K, V>> predicate; 15331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AbstractFilteredMap( 15351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) { 15361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.unfiltered = unfiltered; 15371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.predicate = predicate; 15381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean apply(Object key, V value) { 15411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // This method is called only when the key is in the map, implying that 15421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // key is a K. 15431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 15441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K k = (K) key; 15451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return predicate.apply(Maps.immutableEntry(k, value)); 15461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V put(K key, V value) { 15491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(apply(key, value)); 15501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.put(key, value); 15511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void putAll(Map<? extends K, ? extends V> map) { 15541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<? extends K, ? extends V> entry : map.entrySet()) { 15551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(apply(entry.getKey(), entry.getValue())); 15561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert unfiltered.putAll(map); 15581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object key) { 15611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.containsKey(key) && apply(key, unfiltered.get(key)); 15621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V get(Object key) { 15651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = unfiltered.get(key); 15661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ((value != null) && apply(key, value)) ? value : null; 15671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 15701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet().isEmpty(); 15711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V remove(Object key) { 15741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsKey(key) ? unfiltered.remove(key) : null; 15751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> values; 15781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> values() { 15801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> result = values; 15811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? values = new Values() : result; 15821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class Values extends AbstractCollection<V> { 15851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<V> iterator() { 15861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> entryIterator = entrySet().iterator(); 15871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableIterator<V>() { 15881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 15891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 15901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator.hasNext(); 15911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 15941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V next() { 15951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator.next().getValue(); 15961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 15981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 16011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet().size(); 16021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 16051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet().clear(); 16061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 16091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet().isEmpty(); 16101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 16131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 16141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 16151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 16161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) { 16171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 16181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 16191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 16221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> collection) { 16251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(collection); 16261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 16271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 16281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 16291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 16301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection.contains(entry.getValue()) && predicate.apply(entry)) { 16311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 16321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 16331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 16361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> collection) { 16391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(collection); 16401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 16411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 16421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 16431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 16441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!collection.contains(entry.getValue()) 16451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && predicate.apply(entry)) { 16461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 16471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 16481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 16511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Object[] toArray() { 16541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // creating an ArrayList so filtering happens once 16551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Lists.newArrayList(iterator()).toArray(); 16561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public <T> T[] toArray(T[] array) { 16591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Lists.newArrayList(iterator()).toArray(array); 16601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 16641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when 16651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filtering a filtered sorted map. 16661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 16671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> SortedMap<K, V> filterFiltered( 16681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FilteredEntrySortedMap<K, V> map, 16691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 16701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> predicate 16711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = Predicates.and(map.predicate, entryPredicate); 16721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilteredEntrySortedMap<K, V>(map.sortedMap(), predicate); 16731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class FilteredEntrySortedMap<K, V> 16761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends FilteredEntryMap<K, V> implements SortedMap<K, V> { 16771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FilteredEntrySortedMap(SortedMap<K, V> unfiltered, 16791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 16801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(unfiltered, entryPredicate); 16811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> sortedMap() { 16841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedMap<K, V>) unfiltered; 16851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Comparator<? super K> comparator() { 16881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return sortedMap().comparator(); 16891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K firstKey() { 16921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // correctly throws NoSuchElementException when filtered map is empty. 16931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keySet().iterator().next(); 16941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K lastKey() { 16971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> headMap = sortedMap(); 16981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (true) { 16991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // correctly throws NoSuchElementException when filtered map is empty. 17001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key = headMap.lastKey(); 17011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (apply(key, unfiltered.get(key))) { 17021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return key; 17031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert headMap = sortedMap().headMap(key); 17051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, V> headMap(K toKey) { 17091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilteredEntrySortedMap<K, V>(sortedMap().headMap(toKey), predicate); 17101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, V> subMap(K fromKey, K toKey) { 17131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilteredEntrySortedMap<K, V>( 17141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert sortedMap().subMap(fromKey, toKey), predicate); 17151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedMap<K, V> tailMap(K fromKey) { 17181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilteredEntrySortedMap<K, V>( 17191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert sortedMap().tailMap(fromKey), predicate); 17201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class FilteredKeyMap<K, V> extends AbstractFilteredMap<K, V> { 17241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super K> keyPredicate; 17251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FilteredKeyMap(Map<K, V> unfiltered, Predicate<? super K> keyPredicate, 17271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> entryPredicate) { 17281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(unfiltered, entryPredicate); 17291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.keyPredicate = keyPredicate; 17301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> entrySet; 17331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<K, V>> entrySet() { 17351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> result = entrySet; 17361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) 17371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? entrySet = Sets.filter(unfiltered.entrySet(), predicate) 17381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : result; 17391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> keySet; 17421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> keySet() { 17441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> result = keySet; 17451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) 17461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? keySet = Sets.filter(unfiltered.keySet(), keyPredicate) 17471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : result; 17481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // The cast is called only when the key is in the unfiltered map, implying 17511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // that key is a K. 17521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 17531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 17541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsKey(Object key) { 17551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.containsKey(key) && keyPredicate.apply((K) key); 17561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class FilteredEntryMap<K, V> extends AbstractFilteredMap<K, V> { 17601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 17611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Entries in this set satisfy the predicate, but they don't validate the 17621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * input to {@code Entry.setValue()}. 17631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 17641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Set<Entry<K, V>> filteredEntrySet; 17651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FilteredEntryMap( 17671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 17681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(unfiltered, entryPredicate); 17691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert filteredEntrySet = Sets.filter(unfiltered.entrySet(), predicate); 17701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> entrySet; 17731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<K, V>> entrySet() { 17751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> result = entrySet; 17761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? entrySet = new EntrySet() : result; 17771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class EntrySet extends ForwardingSet<Entry<K, V>> { 17801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Set<Entry<K, V>> delegate() { 17811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filteredEntrySet; 17821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<K, V>> iterator() { 17851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator(); 17861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableIterator<Entry<K, V>>() { 17871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 17881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 17891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.hasNext(); 17901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 17931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Entry<K, V> next() { 17941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Entry<K, V> entry = iterator.next(); 17951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ForwardingMapEntry<K, V>() { 17961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Entry<K, V> delegate() { 17971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry; 17981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V setValue(V value) { 18011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(apply(entry.getKey(), value)); 18021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.setValue(value); 18031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 18051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 18071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> keySet; 18111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> keySet() { 18131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> result = keySet; 18141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? keySet = new KeySet() : result; 18151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class KeySet extends AbstractSet<K> { 18181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<K> iterator() { 18191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator(); 18201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableIterator<K>() { 18211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 18221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 18231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.hasNext(); 18241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 18271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public K next() { 18281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.next().getKey(); 18291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 18311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 18341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filteredEntrySet.size(); 18351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 18381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert filteredEntrySet.clear(); 18391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 18421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsKey(o); 18431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 18461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (containsKey(o)) { 18471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert unfiltered.remove(o); 18481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 18491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 18511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> collection) { 18541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(collection); // for GWT 18551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 18561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object obj : collection) { 18571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed |= remove(obj); 18581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 18601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> collection) { 18631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(collection); // for GWT 18641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 18651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 18661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 18671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 18681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!collection.contains(entry.getKey()) && predicate.apply(entry)) { 18691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 18701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 18711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 18741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Object[] toArray() { 18771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // creating an ArrayList so filtering happens once 18781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Lists.newArrayList(iterator()).toArray(); 18791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public <T> T[] toArray(T[] array) { 18821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Lists.newArrayList(iterator()).toArray(array); 18831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 18881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code AbstractMap} extension that implements {@link #isEmpty()} as {@code 18891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entrySet().isEmpty()} instead of {@code size() == 0} to speed up 18901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implementations where {@code size()} is O(n), and it delegates the {@code 18911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * isEmpty()} methods of its key set and value collection to this 18921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implementation. 18931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 18941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtCompatible 18951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static abstract class ImprovedAbstractMap<K, V> extends AbstractMap<K, V> { 18961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 18971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates the entry set to be returned by {@link #entrySet()}. This method 18981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is invoked at most once on a given map, at the time when {@code entrySet} 18991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is first called. 19001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 19011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected abstract Set<Entry<K, V>> createEntrySet(); 19021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Set<Entry<K, V>> entrySet; 19041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<K, V>> entrySet() { 19061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> result = entrySet; 19071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 19081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet = result = createEntrySet(); 19091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 19111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Set<K> keySet; 19141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> keySet() { 19161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> result = keySet; 19171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 19181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keySet = new KeySet<K, V>() { 19191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Map<K, V> map() { 19201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ImprovedAbstractMap.this; 19211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 19231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 19251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Collection<V> values; 19281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> values() { 19301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> result = values; 19311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 19321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values = new Values<K, V>(){ 19331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Map<K, V> map() { 19341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ImprovedAbstractMap.this; 19351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 19371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 19391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 19421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns {@code true} if this map contains no key-value mappings. 19431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The implementation returns {@code entrySet().isEmpty()}. 19451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code true} if this map contains no key-value mappings 19471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 19481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 19491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet().isEmpty(); 19501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final MapJoiner STANDARD_JOINER = 19541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections2.STANDARD_JOINER.withKeyValueSeparator("="); 19551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 19571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Delegates to {@link Map#get}. Returns {@code null} on {@code 19581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ClassCastException}. 19591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 19601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <V> V safeGet(Map<?, V> map, Object key) { 19611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 19621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.get(key); 19631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ClassCastException e) { 19641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 19651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 19691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Delegates to {@link Map#containsKey}. Returns {@code false} on {@code 19701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ClassCastException} 19711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 19721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static boolean safeContainsKey(Map<?, ?> map, Object key) { 19731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 19741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.containsKey(key); 19751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ClassCastException e) { 19761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 19771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 19811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Implements {@code Collection.contains} safely for forwarding collections of 19821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map entries. If {@code o} is an instance of {@code Map.Entry}, it is 19831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * wrapped using {@link #unmodifiableEntry} to protect against a possible 19841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * nefarious equals method. 19851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that {@code c} is the backing (delegate) collection, rather than 19871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the forwarding collection. 19881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param c the delegate (unwrapped) collection of map entries 19901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param o the object that might be contained in {@code c} 19911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code true} if {@code c} contains {@code o} 19921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 19931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> boolean containsEntryImpl(Collection<Entry<K, V>> c, Object o) { 19941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!(o instanceof Entry)) { 19951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 19961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return c.contains(unmodifiableEntry((Entry<?, ?>) o)); 19981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Implements {@code Collection.remove} safely for forwarding collections of 20021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map entries. If {@code o} is an instance of {@code Map.Entry}, it is 20031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * wrapped using {@link #unmodifiableEntry} to protect against a possible 20041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * nefarious equals method. 20051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 20061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that {@code c} is backing (delegate) collection, rather than the 20071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * forwarding collection. 20081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 20091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param c the delegate (unwrapped) collection of map entries 20101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param o the object to remove from {@code c} 20111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code true} if {@code c} was changed 20121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> boolean removeEntryImpl(Collection<Entry<K, V>> c, Object o) { 20141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!(o instanceof Entry)) { 20151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 20161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return c.remove(unmodifiableEntry((Entry<?, ?>) o)); 20181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link Map#equals}. 20221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static boolean equalsImpl(Map<?, ?> map, Object object) { 20241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map == object) { 20251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 20261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object instanceof Map) { 20281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<?, ?> o = (Map<?, ?>) object; 20291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.entrySet().equals(o.entrySet()); 20301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 20321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link Map#hashCode}. 20361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static int hashCodeImpl(Map<?, ?> map) { 20381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.hashCodeImpl(map.entrySet()); 20391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link Map#toString}. 20431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static String toStringImpl(Map<?, ?> map) { 20451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert StringBuilder sb 20461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = Collections2.newStringBuilderForCollection(map.size()).append('{'); 20471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert STANDARD_JOINER.appendTo(sb, map); 20481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return sb.append('}').toString(); 20491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link Map#putAll}. 20531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> void putAllImpl( 20551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> self, Map<? extends K, ? extends V> map) { 20561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { 20571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert self.put(entry.getKey(), entry.getValue()); 20581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An admittedly inefficient implementation of {@link Map#containsKey}. 20631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static boolean containsKeyImpl(Map<?, ?> map, @Nullable Object key) { 20651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<?, ?> entry : map.entrySet()) { 20661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(entry.getKey(), key)) { 20671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 20681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 20711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link Map#containsValue}. 20751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static boolean containsValueImpl(Map<?, ?> map, @Nullable Object value) { 20771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<?, ?> entry : map.entrySet()) { 20781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(entry.getValue(), value)) { 20791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 20801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 20831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract static class KeySet<K, V> extends AbstractSet<K> { 20861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Map<K, V> map(); 20871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<K> iterator() { 20891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Iterators.transform(map().entrySet().iterator(), 20901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Function<Map.Entry<K, V>, K>() { 20911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K apply(Entry<K, V> entry) { 20921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getKey(); 20931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 20951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 20981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().size(); 20991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 21021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().isEmpty(); 21031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 21061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().containsKey(o); 21071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 21101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (contains(o)) { 21111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map().remove(o); 21121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 21131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 21151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 21181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean removeAll(Collection<?> c) { 21191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(user): find out why this is necessary to make GWT tests pass. 21201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.removeAll(checkNotNull(c)); 21211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 21241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map().clear(); 21251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract static class Values<K, V> extends AbstractCollection<V> { 21291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Map<K, V> map(); 21301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<V> iterator() { 21321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Iterators.transform(map().entrySet().iterator(), 21331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Function<Entry<K, V>, V>() { 21341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V apply(Entry<K, V> entry) { 21351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getValue(); 21361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 21381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 21411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 21421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.remove(o); 21431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 21441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<K, V> entry : map().entrySet()) { 21451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(o, entry.getValue())) { 21461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map().remove(entry.getKey()); 21471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 21481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 21511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 21551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 21561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.removeAll(checkNotNull(c)); 21571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 21581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> toRemove = Sets.newHashSet(); 21591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<K, V> entry : map().entrySet()) { 21601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (c.contains(entry.getValue())) { 21611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert toRemove.add(entry.getKey()); 21621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().keySet().removeAll(toRemove); 21651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 21691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 21701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.retainAll(checkNotNull(c)); 21711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 21721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> toRetain = Sets.newHashSet(); 21731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<K, V> entry : map().entrySet()) { 21741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (c.contains(entry.getValue())) { 21751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert toRetain.add(entry.getKey()); 21761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().keySet().retainAll(toRetain); 21791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 21831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().size(); 21841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 21871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().isEmpty(); 21881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(@Nullable Object o) { 21911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().containsValue(o); 21921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 21951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map().clear(); 21961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract static class EntrySet<K, V> extends AbstractSet<Entry<K, V>> { 22001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Map<K, V> map(); 22011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 22031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().size(); 22041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 22071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map().clear(); 22081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 22111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Entry) { 22121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 22131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = entry.getKey(); 22141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = map().get(key); 22151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Objects.equal(value, entry.getValue()) 22161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && (value != null || map().containsKey(key)); 22171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 22191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 22221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().isEmpty(); 22231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 22261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (contains(o)) { 22271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 22281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().keySet().remove(entry.getKey()); 22291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 22311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 22341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 22351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.removeAll(checkNotNull(c)); 22361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 22371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // if the iterators don't support remove 22381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = true; 22391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object o : c) { 22401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed |= remove(o); 22411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 22431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 22471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 22481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.retainAll(checkNotNull(c)); 22491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (UnsupportedOperationException e) { 22501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // if the iterators don't support remove 22511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Object> keys = Sets.newHashSetWithExpectedSize(c.size()); 22521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object o : c) { 22531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (contains(o)) { 22541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 22551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keys.add(entry.getKey()); 22561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map().keySet().retainAll(keys); 22591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 2263