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