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