Maps.java revision dbd967a6e5c96cc1a97c5521f88dc1564ba2f81b
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; 26dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffinimport 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; 39dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffinimport 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/** 60dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Static utility methods pertaining to {@link Map} instances. Also see this 61dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 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 */ 228dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static <K, V> TreeMap<K, V> newTreeMap( 229dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Nullable Comparator<? super K> comparator) { 230dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin // Ideally, the "? super" 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 /** 272dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns a synchronized (thread-safe) bimap backed by the specified bimap. 273dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * In order to guarantee serial access, it is critical that <b>all</b> access 274dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * to the backing bimap is accomplished through the returned bimap. 275dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 276dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * <p>It is imperative that the user manually synchronize on the returned map 277dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * when accessing any of its collection views: <pre> {@code 278dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 279dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * BiMap<Long, String> map = Maps.synchronizedBiMap( 280dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * HashBiMap.<Long, String>create()); 281dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * ... 282dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Set<Long> set = map.keySet(); // Needn't be in synchronized block 283dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * ... 284dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * synchronized (map) { // Synchronizing on map, not set! 285dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Iterator<Long> it = set.iterator(); // Must be in synchronized block 286dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * while (it.hasNext()) { 287dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * foo(it.next()); 288dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * } 289dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * }}</pre> 290dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 291dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Failure to follow this advice may result in non-deterministic behavior. 292dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 293dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * <p>The returned bimap will be serializable if the specified bimap is 294dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * serializable. 295dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 296dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param bimap the bimap to be wrapped in a synchronized view 297dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return a sychronized view of the specified bimap 298dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 299dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) { 300dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return Synchronized.biMap(bimap, null); 301dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 302dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 303dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 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 } 327dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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) { 499dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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 */ 536dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @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 /** 622dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an immutable map for which the {@link Map#values} are the given 623dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * elements in the given order, and each key is the product of invoking a 624dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * supplied function on its corresponding value. 6253c77433663281544363151bf284b0240dfd22a42Paul Duffin * 626dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param values the values to use when constructing the {@code Map} 627dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param keyFunction the function used to produce the key for each value 628dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return a map mapping the result of evaluating the function {@code 629dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * keyFunction} on each value in the input collection to that value 630dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws IllegalArgumentException if {@code keyFunction} produces the same 631dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * key for more than one value in the input collection 632dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws NullPointerException if any elements of {@code values} is null, or 633dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * if {@code keyFunction} produces {@code null} for any value 6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 635dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static <K, V> ImmutableMap<K, V> uniqueIndex( 636dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Iterable<V> values, Function<? super V, K> keyFunction) { 637dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return uniqueIndex(values.iterator(), keyFunction); 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 641dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * <b>Deprecated.</b> 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 643dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @since 10.0 644dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @deprecated use {@link #uniqueIndex(Iterator, Function)} by casting {@code 645dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * values} to {@code Iterator<V>}, or better yet, by implementing only 646dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled 647dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * for deletion in March 2012.</b> 6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6493c77433663281544363151bf284b0240dfd22a42Paul Duffin @Beta 650dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Deprecated 651dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static <K, V, I extends Object & Iterable<V> & Iterator<V>> 652dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin ImmutableMap<K, V> uniqueIndex( 653dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin I values, Function<? super V, K> keyFunction) { 654dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Iterable<V> valuesIterable = checkNotNull(values); 655dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return uniqueIndex(valuesIterable, keyFunction); 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 659dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an immutable map for which the {@link Map#values} are the given 660dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * elements in the given order, and each key is the product of invoking a 661dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * supplied function on its corresponding value. 6623c77433663281544363151bf284b0240dfd22a42Paul Duffin * 663dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param values the values to use when constructing the {@code Map} 664dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param keyFunction the function used to produce the key for each value 665dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return a map mapping the result of evaluating the function {@code 666dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * keyFunction} on each value in the input collection to that value 667dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws IllegalArgumentException if {@code keyFunction} produces the same 668dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * key for more than one value in the input collection 669dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws NullPointerException if any elements of {@code values} is null, or 670dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * if {@code keyFunction} produces {@code null} for any value 671dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @since 10.0 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 673dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static <K, V> ImmutableMap<K, V> uniqueIndex( 674dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Iterator<V> values, Function<? super V, K> keyFunction) { 675dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin checkNotNull(keyFunction); 676dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin ImmutableMap.Builder<K, V> builder = ImmutableMap.builder(); 677dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin while (values.hasNext()) { 678dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin V value = values.next(); 679dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin builder.put(keyFunction.apply(value), value); 6803c77433663281544363151bf284b0240dfd22a42Paul Duffin } 681dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return builder.build(); 682dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 684dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 685dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Creates an {@code ImmutableMap<String, String>} from a {@code Properties} 686dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * instance. Properties normally derive from {@code Map<Object, Object>}, but 687dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * they typically contain strings, which is awkward. This method lets you get 688dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * a plain-old-{@code Map} out of a {@code Properties}. 689dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 690dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param properties a {@code Properties} object to be converted 691dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return an immutable map containing all the entries in {@code properties} 692dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws ClassCastException if any key in {@code Properties} is not a {@code 693dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * String} 694dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @throws NullPointerException if any key or value in {@code Properties} is 695dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * null 696dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 697dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @GwtIncompatible("java.util.Properties") 698dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static ImmutableMap<String, String> fromProperties( 699dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Properties properties) { 700dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); 7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 702dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) { 703dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin String key = (String) e.nextElement(); 704dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin builder.put(key, properties.getProperty(key)); 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 707dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return builder.build(); 708dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 710dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 711dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an immutable map entry with the specified key and value. The {@link 712dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 713dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 714dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * <p>The returned entry is serializable. 715dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 716dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param key the key to be associated with the returned entry 717dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param value the value to be associated with the returned entry 718dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 719dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @GwtCompatible(serializable = true) 720dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static <K, V> Entry<K, V> immutableEntry( 721dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Nullable K key, @Nullable V value) { 722dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return new ImmutableEntry<K, V>(key, value); 723dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 7243c77433663281544363151bf284b0240dfd22a42Paul Duffin 725dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 726dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an unmodifiable view of the specified set of entries. The {@link 727dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Entry#setValue} operation throws an {@link UnsupportedOperationException}, 728dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * as do any operations that would modify the returned set. 729dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 730dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param entrySet the entries for which to return an unmodifiable view 731dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return an unmodifiable view of the entries 732dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 733dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin static <K, V> Set<Entry<K, V>> unmodifiableEntrySet( 734dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Set<Entry<K, V>> entrySet) { 735dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return new UnmodifiableEntrySet<K, V>( 736dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Collections.unmodifiableSet(entrySet)); 737dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 7383c77433663281544363151bf284b0240dfd22a42Paul Duffin 739dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 740dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns an unmodifiable view of the specified map entry. The {@link 741dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 742dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * This also has the side-effect of redefining {@code equals} to comply with 743dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * the Entry contract, to avoid a possible nefarious implementation of equals. 744dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 745dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @param entry the entry for which to return an unmodifiable view 746dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return an unmodifiable view of the entry 747dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 748dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin static <K, V> Entry<K, V> unmodifiableEntry(final Entry<K, V> entry) { 749dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin checkNotNull(entry); 750dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return new AbstractMapEntry<K, V>() { 751dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public K getKey() { 752dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return entry.getKey(); 7533c77433663281544363151bf284b0240dfd22a42Paul Duffin } 7543c77433663281544363151bf284b0240dfd22a42Paul Duffin 755dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public V getValue() { 756dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return entry.getValue(); 7573c77433663281544363151bf284b0240dfd22a42Paul Duffin } 758dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }; 759dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 760dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 761dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** @see Multimaps#unmodifiableEntries */ 762dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin static class UnmodifiableEntries<K, V> 763dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin extends ForwardingCollection<Entry<K, V>> { 764dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin private final Collection<Entry<K, V>> entries; 765dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 766dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin UnmodifiableEntries(Collection<Entry<K, V>> entries) { 767dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin this.entries = entries; 7683c77433663281544363151bf284b0240dfd22a42Paul Duffin } 7693c77433663281544363151bf284b0240dfd22a42Paul Duffin 770dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override protected Collection<Entry<K, V>> delegate() { 771dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return entries; 7723c77433663281544363151bf284b0240dfd22a42Paul Duffin } 7733c77433663281544363151bf284b0240dfd22a42Paul Duffin 774dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public Iterator<Entry<K, V>> iterator() { 775dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin final Iterator<Entry<K, V>> delegate = super.iterator(); 776dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return new ForwardingIterator<Entry<K, V>>() { 777dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public Entry<K, V> next() { 778dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return unmodifiableEntry(super.next()); 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 781dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public void remove() { 782dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 783dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 784dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 785dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override protected Iterator<Entry<K, V>> delegate() { 786dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return delegate; 7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 791dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin // See java.util.Collections.UnmodifiableEntrySet for details on attacks. 7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 793dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public boolean add(Entry<K, V> element) { 794dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 797dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public boolean addAll( 798dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Collection<? extends Entry<K, V>> collection) { 799dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 802dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public void clear() { 803dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 806dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public boolean remove(Object object) { 807dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 810dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public boolean removeAll(Collection<?> collection) { 811dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 814dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public boolean retainAll(Collection<?> collection) { 815dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin throw new UnsupportedOperationException(); 8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 818dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public Object[] toArray() { 819dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return standardToArray(); 8203c77433663281544363151bf284b0240dfd22a42Paul Duffin } 8213c77433663281544363151bf284b0240dfd22a42Paul Duffin 822dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public <T> T[] toArray(T[] array) { 823dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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; 868dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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( 942dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Map<K, V1> fromMap, final Function<? super V1, V2> function) { 943dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin checkNotNull(function); 944dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin EntryTransformer<K, V1, V2> transformer = 945dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin new EntryTransformer<K, V1, V2>() { 946dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override 947dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public V2 transformEntry(K key, V1 value) { 948dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return function.apply(value); 949dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 950dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }; 951dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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 */ 993dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Beta 9941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V1, V2> SortedMap<K, V2> transformValues( 995dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin SortedMap<K, V1> fromMap, final Function<? super V1, V2> function) { 9961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(function); 997dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin EntryTransformer<K, V1, V2> transformer = 998dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin new EntryTransformer<K, V1, V2>() { 999dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override 1000dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public V2 transformEntry(K key, V1 value) { 1001dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return function.apply(value); 1002dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1003dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }; 1004dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return transformEntries(fromMap, transformer); 10051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1007dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 1008dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns a view of a map whose values are derived from the original map's 1009dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * entries. In contrast to {@link #transformValues}, this method's 1010dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 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 = 1016dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 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) { 1020dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * return value ? key : "no" + key; 10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 10221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 1023dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Map<String, String> transformed = 1024dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Maps.transformEntries(options, flagPrefixer); 10251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 10261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1027dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * ... 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 * 1056dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @since 7.0 10571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1058dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static <K, V1, V2> Map<K, V2> transformEntries( 1059dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Map<K, V1> fromMap, 10603c77433663281544363151bf284b0240dfd22a42Paul Duffin EntryTransformer<? super K, ? super V1, V2> transformer) { 1061dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin if (fromMap instanceof SortedMap) { 1062dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return transformEntries((SortedMap<K, V1>) fromMap, transformer); 1063dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1064dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return new TransformedEntriesMap<K, V1, V2>(fromMap, transformer); 10653c77433663281544363151bf284b0240dfd22a42Paul Duffin } 10663c77433663281544363151bf284b0240dfd22a42Paul Duffin 10673c77433663281544363151bf284b0240dfd22a42Paul Duffin /** 1068dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns a view of a sorted map whose values are derived from the original 1069dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * sorted map's entries. In contrast to {@link #transformValues}, this 1070dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * method's entry-transformation logic may depend on the key as well as the 1071dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * value. 10723c77433663281544363151bf284b0240dfd22a42Paul Duffin * 10733c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p>All other properties of the transformed map, such as iteration order, 10743c77433663281544363151bf284b0240dfd22a42Paul Duffin * are left intact. For example, the code: <pre> {@code 10753c77433663281544363151bf284b0240dfd22a42Paul Duffin * 1076dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Map<String, Boolean> options = 1077dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * ImmutableSortedMap.of("verbose", true, "sort", false); 10783c77433663281544363151bf284b0240dfd22a42Paul Duffin * EntryTransformer<String, Boolean, String> flagPrefixer = 10793c77433663281544363151bf284b0240dfd22a42Paul Duffin * new EntryTransformer<String, Boolean, String>() { 10803c77433663281544363151bf284b0240dfd22a42Paul Duffin * public String transformEntry(String key, Boolean value) { 1081dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * return value ? key : "yes" + key; 10823c77433663281544363151bf284b0240dfd22a42Paul Duffin * } 10833c77433663281544363151bf284b0240dfd22a42Paul Duffin * }; 1084dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * SortedMap<String, String> transformed = 1085dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * LabsMaps.transformSortedEntries(options, flagPrefixer); 10863c77433663281544363151bf284b0240dfd22a42Paul Duffin * System.out.println(transformed);}</pre> 10873c77433663281544363151bf284b0240dfd22a42Paul Duffin * 10883c77433663281544363151bf284b0240dfd22a42Paul Duffin * ... prints {@code {sort=yessort, verbose=verbose}}. 10893c77433663281544363151bf284b0240dfd22a42Paul Duffin * 1090dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * <p>Changes in the underlying map are reflected in this view. Conversely, 1091dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * this view supports removal operations, and these are reflected in the 1092dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * underlying map. 10933c77433663281544363151bf284b0240dfd22a42Paul Duffin * 10943c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p>It's acceptable for the underlying map to contain null keys and null 10953c77433663281544363151bf284b0240dfd22a42Paul Duffin * values provided that the transformer is capable of accepting null inputs. 10963c77433663281544363151bf284b0240dfd22a42Paul Duffin * The transformed map might contain null values if the transformer sometimes 10973c77433663281544363151bf284b0240dfd22a42Paul Duffin * gives a null result. 10983c77433663281544363151bf284b0240dfd22a42Paul Duffin * 10993c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p>The returned map is not thread-safe or serializable, even if the 11003c77433663281544363151bf284b0240dfd22a42Paul Duffin * underlying map is. 11013c77433663281544363151bf284b0240dfd22a42Paul Duffin * 11023c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p>The transformer is applied lazily, invoked when needed. This is 11033c77433663281544363151bf284b0240dfd22a42Paul Duffin * necessary for the returned map to be a view, but it means that the 11043c77433663281544363151bf284b0240dfd22a42Paul Duffin * transformer will be applied many times for bulk operations like {@link 11053c77433663281544363151bf284b0240dfd22a42Paul Duffin * Map#containsValue} and {@link Object#toString}. For this to perform well, 11063c77433663281544363151bf284b0240dfd22a42Paul Duffin * {@code transformer} should be fast. To avoid lazy evaluation when the 11073c77433663281544363151bf284b0240dfd22a42Paul Duffin * returned map doesn't need to be a view, copy the returned map into a new 11083c77433663281544363151bf284b0240dfd22a42Paul Duffin * map of your choosing. 11093c77433663281544363151bf284b0240dfd22a42Paul Duffin * 11103c77433663281544363151bf284b0240dfd22a42Paul Duffin * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 11113c77433663281544363151bf284b0240dfd22a42Paul Duffin * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 11123c77433663281544363151bf284b0240dfd22a42Paul Duffin * that {@code k2} is also of type {@code K}. Using an {@code 11133c77433663281544363151bf284b0240dfd22a42Paul Duffin * EntryTransformer} key type for which this may not hold, such as {@code 11143c77433663281544363151bf284b0240dfd22a42Paul Duffin * ArrayList}, may risk a {@code ClassCastException} when calling methods on 11153c77433663281544363151bf284b0240dfd22a42Paul Duffin * the transformed map. 11163c77433663281544363151bf284b0240dfd22a42Paul Duffin * 1117dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @since 11.0 11183c77433663281544363151bf284b0240dfd22a42Paul Duffin */ 1119dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Beta 1120dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static <K, V1, V2> SortedMap<K, V2> transformEntries( 1121dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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() { 1213dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin final Iterator<Entry<K, V1>> backingIterator = 1214dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin fromMap.entrySet().iterator(); 1215dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return Iterators.transform(backingIterator, 1216dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin new Function<Entry<K, V1>, Entry<K, V2>>() { 1217dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public Entry<K, V2> apply(Entry<K, V1> entry) { 1218dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return immutableEntry( 1219dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin entry.getKey(), 1220dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin transformer.transformEntry(entry.getKey(), 1221dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin entry.getValue())); 12221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1223dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }); 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 } 12813c77433663281544363151bf284b0240dfd22a42Paul Duffin 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); 1318dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Predicate<Entry<K, V>> entryPredicate = 1319dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin new Predicate<Entry<K, V>>() { 1320dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override 1321dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public boolean apply(Entry<K, V> input) { 1322dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return keyPredicate.apply(input.getKey()); 1323dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1324dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }; 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 */ 1361dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Beta 13621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedMap<K, V> filterKeys( 13631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 1364dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin // TODO: Return a subclass of Maps.FilteredKeyMap for slightly better 13651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // performance. 13661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(keyPredicate); 1367dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Predicate<Entry<K, V>> entryPredicate = new Predicate<Entry<K, V>>() { 1368dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override 1369dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public boolean apply(Entry<K, V> input) { 1370dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return keyPredicate.apply(input.getKey()); 1371dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1372dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }; 1373dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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 } 1410dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin checkNotNull(valuePredicate); 1411dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Predicate<Entry<K, V>> entryPredicate = 1412dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin new Predicate<Entry<K, V>>() { 1413dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override 1414dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public boolean apply(Entry<K, V> input) { 1415dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return valuePredicate.apply(input.getValue()); 1416dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1417dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }; 1418dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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 */ 1452dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Beta 14531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedMap<K, V> filterValues( 14541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 1455dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin checkNotNull(valuePredicate); 1456dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin Predicate<Entry<K, V>> entryPredicate = 1457dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin new Predicate<Entry<K, V>>() { 1458dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override 1459dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public boolean apply(Entry<K, V> input) { 1460dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return valuePredicate.apply(input.getValue()); 1461dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1462dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }; 1463dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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) { 1498dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return filterEntries((SortedMap<K, V>) unfiltered, entryPredicate); 1499dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 15003c77433663281544363151bf284b0240dfd22a42Paul Duffin checkNotNull(entryPredicate); 1501dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return (unfiltered instanceof AbstractFilteredMap) 1502dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate) 1503dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin : 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 * 1535dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @since 11.0 15361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1537dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Beta 1538dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public static <K, V> SortedMap<K, V> filterEntries( 1539dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin SortedMap<K, V> unfiltered, 15401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 15411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entryPredicate); 1542dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return (unfiltered instanceof FilteredEntrySortedMap) 1543dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin ? filterFiltered((FilteredEntrySortedMap<K, V>) unfiltered, entryPredicate) 1544dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin : 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; 1843dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return (result == null) ? keySet = new KeySet() : result; 18441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1846dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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 1882dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public boolean removeAll(Collection<?> collection) { 1883dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin checkNotNull(collection); // for GWT 1884dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin boolean changed = false; 1885dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin for (Object obj : collection) { 1886dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin changed |= remove(obj); 1887dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1888dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return changed; 1889dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 1890dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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(); 1897dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin if (!collection.contains(entry.getKey()) && predicate.apply(entry)) { 18981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 18991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 19001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1902dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return changed; 1903dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 19043c77433663281544363151bf284b0240dfd22a42Paul Duffin 1905dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public Object[] toArray() { 1906dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin // creating an ArrayList so filtering happens once 1907dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return Lists.newArrayList(iterator()).toArray(); 1908dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 19091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1910dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public <T> T[] toArray(T[] array) { 1911dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return Lists.newArrayList(iterator()).toArray(array); 1912dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 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 1924dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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) { 1961dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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 } 1969dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 1970dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 1971dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * Returns {@code true} if this map contains no key-value mappings. 1972dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 1973dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * <p>The implementation returns {@code entrySet().isEmpty()}. 1974dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 1975dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * @return {@code true} if this map contains no key-value mappings 1976dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 1977dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public boolean isEmpty() { 1978dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return entrySet().isEmpty(); 1979dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 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 1987dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 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 1999dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * 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 /** 2064dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin * An implementation of {@link Map#hashCode}. 2065dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin */ 2066dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin static int hashCodeImpl(Map<?, ?> map) { 2067dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return Sets.hashCodeImpl(map.entrySet()); 2068dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 2069dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 2070dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin /** 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) { 2094dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin for (Entry<?, ?> entry : map.entrySet()) { 2095dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin if (Objects.equal(entry.getKey(), key)) { 2096dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return true; 2097dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 2098dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 2099dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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) { 2106dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin for (Entry<?, ?> entry : map.entrySet()) { 2107dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin if (Objects.equal(entry.getValue(), value)) { 2108dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return true; 21091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2110dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 2111dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return false; 21121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2114dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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() { 2118dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return Iterators.transform(map().entrySet().iterator(), 2119dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin new Function<Map.Entry<K, V>, K>() { 2120dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public K apply(Entry<K, V> entry) { 2121dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return entry.getKey(); 2122dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 2123dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }); 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 21463c77433663281544363151bf284b0240dfd22a42Paul Duffin @Override 2147dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin public boolean removeAll(Collection<?> c) { 2148dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin // TODO(user): find out why this is necessary to make GWT tests pass. 2149dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return super.removeAll(checkNotNull(c)); 21503c77433663281544363151bf284b0240dfd22a42Paul Duffin } 21513c77433663281544363151bf284b0240dfd22a42Paul Duffin 2152dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public void clear() { 2153dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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() { 2161dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return Iterators.transform(map().entrySet().iterator(), 2162dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin new Function<Entry<K, V>, V>() { 2163dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin @Override public V apply(Entry<K, V> entry) { 2164dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin return entry.getValue(); 2165dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin } 2166dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin }); 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 2228dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 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