001/*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import static com.google.common.base.Preconditions.checkArgument;
020import static com.google.common.base.Preconditions.checkNotNull;
021import static com.google.common.base.Predicates.compose;
022import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
023import static com.google.common.collect.CollectPreconditions.checkNonnegative;
024
025import com.google.common.annotations.Beta;
026import com.google.common.annotations.GwtCompatible;
027import com.google.common.annotations.GwtIncompatible;
028import com.google.common.base.Converter;
029import com.google.common.base.Equivalence;
030import com.google.common.base.Function;
031import com.google.common.base.Objects;
032import com.google.common.base.Preconditions;
033import com.google.common.base.Predicate;
034import com.google.common.base.Predicates;
035import com.google.common.collect.MapDifference.ValueDifference;
036import com.google.common.primitives.Ints;
037import com.google.errorprone.annotations.CanIgnoreReturnValue;
038import com.google.j2objc.annotations.RetainedWith;
039import com.google.j2objc.annotations.Weak;
040import com.google.j2objc.annotations.WeakOuter;
041import java.io.Serializable;
042import java.util.AbstractCollection;
043import java.util.AbstractMap;
044import java.util.Collection;
045import java.util.Collections;
046import java.util.Comparator;
047import java.util.EnumMap;
048import java.util.Enumeration;
049import java.util.HashMap;
050import java.util.IdentityHashMap;
051import java.util.Iterator;
052import java.util.LinkedHashMap;
053import java.util.Map;
054import java.util.Map.Entry;
055import java.util.NavigableMap;
056import java.util.NavigableSet;
057import java.util.Properties;
058import java.util.Set;
059import java.util.SortedMap;
060import java.util.SortedSet;
061import java.util.TreeMap;
062import java.util.concurrent.ConcurrentHashMap;
063import java.util.concurrent.ConcurrentMap;
064import org.checkerframework.checker.nullness.compatqual.NullableDecl;
065
066/**
067 * Static utility methods pertaining to {@link Map} instances (including instances of {@link
068 * SortedMap}, {@link BiMap}, etc.). Also see this class's counterparts {@link Lists}, {@link Sets}
069 * and {@link Queues}.
070 *
071 * <p>See the Guava User Guide article on <a href=
072 * "https://github.com/google/guava/wiki/CollectionUtilitiesExplained#maps"> {@code Maps}</a>.
073 *
074 * @author Kevin Bourrillion
075 * @author Mike Bostock
076 * @author Isaac Shum
077 * @author Louis Wasserman
078 * @since 2.0
079 */
080@GwtCompatible(emulated = true)
081public final class Maps {
082  private Maps() {}
083
084  private enum EntryFunction implements Function<Entry<?, ?>, Object> {
085    KEY {
086      @Override
087      @NullableDecl
088      public Object apply(Entry<?, ?> entry) {
089        return entry.getKey();
090      }
091    },
092    VALUE {
093      @Override
094      @NullableDecl
095      public Object apply(Entry<?, ?> entry) {
096        return entry.getValue();
097      }
098    };
099  }
100
101  @SuppressWarnings("unchecked")
102  static <K> Function<Entry<K, ?>, K> keyFunction() {
103    return (Function) EntryFunction.KEY;
104  }
105
106  @SuppressWarnings("unchecked")
107  static <V> Function<Entry<?, V>, V> valueFunction() {
108    return (Function) EntryFunction.VALUE;
109  }
110
111  static <K, V> Iterator<K> keyIterator(Iterator<Entry<K, V>> entryIterator) {
112    return new TransformedIterator<Entry<K, V>, K>(entryIterator) {
113      @Override
114      K transform(Entry<K, V> entry) {
115        return entry.getKey();
116      }
117    };
118  }
119
120  static <K, V> Iterator<V> valueIterator(Iterator<Entry<K, V>> entryIterator) {
121    return new TransformedIterator<Entry<K, V>, V>(entryIterator) {
122      @Override
123      V transform(Entry<K, V> entry) {
124        return entry.getValue();
125      }
126    };
127  }
128
129  /**
130   * Returns an immutable map instance containing the given entries. Internally, the returned map
131   * will be backed by an {@link EnumMap}.
132   *
133   * <p>The iteration order of the returned map follows the enum's iteration order, not the order in
134   * which the elements appear in the given map.
135   *
136   * @param map the map to make an immutable copy of
137   * @return an immutable map containing those entries
138   * @since 14.0
139   */
140  @GwtCompatible(serializable = true)
141  public static <K extends Enum<K>, V> ImmutableMap<K, V> immutableEnumMap(
142      Map<K, ? extends V> map) {
143    if (map instanceof ImmutableEnumMap) {
144      @SuppressWarnings("unchecked") // safe covariant cast
145      ImmutableEnumMap<K, V> result = (ImmutableEnumMap<K, V>) map;
146      return result;
147    }
148    Iterator<? extends Entry<K, ? extends V>> entryItr = map.entrySet().iterator();
149    if (!entryItr.hasNext()) {
150      return ImmutableMap.of();
151    }
152    Entry<K, ? extends V> entry1 = entryItr.next();
153    K key1 = entry1.getKey();
154    V value1 = entry1.getValue();
155    checkEntryNotNull(key1, value1);
156    Class<K> clazz = key1.getDeclaringClass();
157    EnumMap<K, V> enumMap = new EnumMap<>(clazz);
158    enumMap.put(key1, value1);
159    while (entryItr.hasNext()) {
160      Entry<K, ? extends V> entry = entryItr.next();
161      K key = entry.getKey();
162      V value = entry.getValue();
163      checkEntryNotNull(key, value);
164      enumMap.put(key, value);
165    }
166    return ImmutableEnumMap.asImmutable(enumMap);
167  }
168
169  /**
170   * Creates a <i>mutable</i>, empty {@code HashMap} instance.
171   *
172   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#of()} instead.
173   *
174   * <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link #newEnumMap} instead.
175   *
176   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
177   * deprecated. Instead, use the {@code HashMap} constructor directly, taking advantage of the new
178   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
179   *
180   * @return a new, empty {@code HashMap}
181   */
182  public static <K, V> HashMap<K, V> newHashMap() {
183    return new HashMap<>();
184  }
185
186  /**
187   * Creates a <i>mutable</i> {@code HashMap} instance with the same mappings as the specified map.
188   *
189   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#copyOf(Map)} instead.
190   *
191   * <p><b>Note:</b> if {@code K} is an {@link Enum} type, use {@link #newEnumMap} instead.
192   *
193   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
194   * deprecated. Instead, use the {@code HashMap} constructor directly, taking advantage of the new
195   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
196   *
197   * @param map the mappings to be placed in the new map
198   * @return a new {@code HashMap} initialized with the mappings from {@code map}
199   */
200  public static <K, V> HashMap<K, V> newHashMap(Map<? extends K, ? extends V> map) {
201    return new HashMap<>(map);
202  }
203
204  /**
205   * Creates a {@code HashMap} instance, with a high enough "initial capacity" that it <i>should</i>
206   * hold {@code expectedSize} elements without growth. This behavior cannot be broadly guaranteed,
207   * but it is observed to be true for OpenJDK 1.7. It also can't be guaranteed that the method
208   * isn't inadvertently <i>oversizing</i> the returned map.
209   *
210   * @param expectedSize the number of entries you expect to add to the returned map
211   * @return a new, empty {@code HashMap} with enough capacity to hold {@code expectedSize} entries
212   *     without resizing
213   * @throws IllegalArgumentException if {@code expectedSize} is negative
214   */
215  public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize) {
216    return new HashMap<>(capacity(expectedSize));
217  }
218
219  /**
220   * Returns a capacity that is sufficient to keep the map from being resized as long as it grows no
221   * larger than expectedSize and the load factor is ≥ its default (0.75).
222   */
223  static int capacity(int expectedSize) {
224    if (expectedSize < 3) {
225      checkNonnegative(expectedSize, "expectedSize");
226      return expectedSize + 1;
227    }
228    if (expectedSize < Ints.MAX_POWER_OF_TWO) {
229      // This is the calculation used in JDK8 to resize when a putAll
230      // happens; it seems to be the most conservative calculation we
231      // can make.  0.75 is the default load factor.
232      return (int) ((float) expectedSize / 0.75F + 1.0F);
233    }
234    return Integer.MAX_VALUE; // any large value
235  }
236
237  /**
238   * Creates a <i>mutable</i>, empty, insertion-ordered {@code LinkedHashMap} instance.
239   *
240   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#of()} instead.
241   *
242   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
243   * deprecated. Instead, use the {@code LinkedHashMap} constructor directly, taking advantage of
244   * the new <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
245   *
246   * @return a new, empty {@code LinkedHashMap}
247   */
248  public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() {
249    return new LinkedHashMap<>();
250  }
251
252  /**
253   * Creates a <i>mutable</i>, insertion-ordered {@code LinkedHashMap} instance with the same
254   * mappings as the specified map.
255   *
256   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#copyOf(Map)} instead.
257   *
258   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
259   * deprecated. Instead, use the {@code LinkedHashMap} constructor directly, taking advantage of
260   * the new <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
261   *
262   * @param map the mappings to be placed in the new map
263   * @return a new, {@code LinkedHashMap} initialized with the mappings from {@code map}
264   */
265  public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> map) {
266    return new LinkedHashMap<>(map);
267  }
268
269  /**
270   * Creates a {@code LinkedHashMap} instance, with a high enough "initial capacity" that it
271   * <i>should</i> hold {@code expectedSize} elements without growth. This behavior cannot be
272   * broadly guaranteed, but it is observed to be true for OpenJDK 1.7. It also can't be guaranteed
273   * that the method isn't inadvertently <i>oversizing</i> the returned map.
274   *
275   * @param expectedSize the number of entries you expect to add to the returned map
276   * @return a new, empty {@code LinkedHashMap} with enough capacity to hold {@code expectedSize}
277   *     entries without resizing
278   * @throws IllegalArgumentException if {@code expectedSize} is negative
279   * @since 19.0
280   */
281  public static <K, V> LinkedHashMap<K, V> newLinkedHashMapWithExpectedSize(int expectedSize) {
282    return new LinkedHashMap<>(capacity(expectedSize));
283  }
284
285  /**
286   * Creates a new empty {@link ConcurrentHashMap} instance.
287   *
288   * @since 3.0
289   */
290  public static <K, V> ConcurrentMap<K, V> newConcurrentMap() {
291    return new ConcurrentHashMap<>();
292  }
293
294  /**
295   * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the natural ordering of its
296   * elements.
297   *
298   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableSortedMap#of()} instead.
299   *
300   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
301   * deprecated. Instead, use the {@code TreeMap} constructor directly, taking advantage of the new
302   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
303   *
304   * @return a new, empty {@code TreeMap}
305   */
306  public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() {
307    return new TreeMap<>();
308  }
309
310  /**
311   * Creates a <i>mutable</i> {@code TreeMap} instance with the same mappings as the specified map
312   * and using the same ordering as the specified map.
313   *
314   * <p><b>Note:</b> if mutability is not required, use {@link
315   * ImmutableSortedMap#copyOfSorted(SortedMap)} instead.
316   *
317   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
318   * deprecated. Instead, use the {@code TreeMap} constructor directly, taking advantage of the new
319   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
320   *
321   * @param map the sorted map whose mappings are to be placed in the new map and whose comparator
322   *     is to be used to sort the new map
323   * @return a new {@code TreeMap} initialized with the mappings from {@code map} and using the
324   *     comparator of {@code map}
325   */
326  public static <K, V> TreeMap<K, V> newTreeMap(SortedMap<K, ? extends V> map) {
327    return new TreeMap<>(map);
328  }
329
330  /**
331   * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the given comparator.
332   *
333   * <p><b>Note:</b> if mutability is not required, use {@code
334   * ImmutableSortedMap.orderedBy(comparator).build()} instead.
335   *
336   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
337   * deprecated. Instead, use the {@code TreeMap} constructor directly, taking advantage of the new
338   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
339   *
340   * @param comparator the comparator to sort the keys with
341   * @return a new, empty {@code TreeMap}
342   */
343  public static <C, K extends C, V> TreeMap<K, V> newTreeMap(
344      @NullableDecl Comparator<C> comparator) {
345    // Ideally, the extra type parameter "C" shouldn't be necessary. It is a
346    // work-around of a compiler type inference quirk that prevents the
347    // following code from being compiled:
348    // Comparator<Class<?>> comparator = null;
349    // Map<Class<? extends Throwable>, String> map = newTreeMap(comparator);
350    return new TreeMap<>(comparator);
351  }
352
353  /**
354   * Creates an {@code EnumMap} instance.
355   *
356   * @param type the key type for this map
357   * @return a new, empty {@code EnumMap}
358   */
359  public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Class<K> type) {
360    return new EnumMap<>(checkNotNull(type));
361  }
362
363  /**
364   * Creates an {@code EnumMap} with the same mappings as the specified map.
365   *
366   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
367   * deprecated. Instead, use the {@code EnumMap} constructor directly, taking advantage of the new
368   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
369   *
370   * @param map the map from which to initialize this {@code EnumMap}
371   * @return a new {@code EnumMap} initialized with the mappings from {@code map}
372   * @throws IllegalArgumentException if {@code m} is not an {@code EnumMap} instance and contains
373   *     no mappings
374   */
375  public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Map<K, ? extends V> map) {
376    return new EnumMap<>(map);
377  }
378
379  /**
380   * Creates an {@code IdentityHashMap} instance.
381   *
382   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
383   * deprecated. Instead, use the {@code IdentityHashMap} constructor directly, taking advantage of
384   * the new <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
385   *
386   * @return a new, empty {@code IdentityHashMap}
387   */
388  public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() {
389    return new IdentityHashMap<>();
390  }
391
392  /**
393   * Computes the difference between two maps. This difference is an immutable snapshot of the state
394   * of the maps at the time this method is called. It will never change, even if the maps change at
395   * a later time.
396   *
397   * <p>Since this method uses {@code HashMap} instances internally, the keys of the supplied maps
398   * must be well-behaved with respect to {@link Object#equals} and {@link Object#hashCode}.
399   *
400   * <p><b>Note:</b>If you only need to know whether two maps have the same mappings, call {@code
401   * left.equals(right)} instead of this method.
402   *
403   * @param left the map to treat as the "left" map for purposes of comparison
404   * @param right the map to treat as the "right" map for purposes of comparison
405   * @return the difference between the two maps
406   */
407  @SuppressWarnings("unchecked")
408  public static <K, V> MapDifference<K, V> difference(
409      Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right) {
410    if (left instanceof SortedMap) {
411      SortedMap<K, ? extends V> sortedLeft = (SortedMap<K, ? extends V>) left;
412      return difference(sortedLeft, right);
413    }
414    return difference(left, right, Equivalence.equals());
415  }
416
417  /**
418   * Computes the difference between two maps. This difference is an immutable snapshot of the state
419   * of the maps at the time this method is called. It will never change, even if the maps change at
420   * a later time.
421   *
422   * <p>Since this method uses {@code HashMap} instances internally, the keys of the supplied maps
423   * must be well-behaved with respect to {@link Object#equals} and {@link Object#hashCode}.
424   *
425   * @param left the map to treat as the "left" map for purposes of comparison
426   * @param right the map to treat as the "right" map for purposes of comparison
427   * @param valueEquivalence the equivalence relationship to use to compare values
428   * @return the difference between the two maps
429   * @since 10.0
430   */
431  public static <K, V> MapDifference<K, V> difference(
432      Map<? extends K, ? extends V> left,
433      Map<? extends K, ? extends V> right,
434      Equivalence<? super V> valueEquivalence) {
435    Preconditions.checkNotNull(valueEquivalence);
436
437    Map<K, V> onlyOnLeft = newLinkedHashMap();
438    Map<K, V> onlyOnRight = new LinkedHashMap<>(right); // will whittle it down
439    Map<K, V> onBoth = newLinkedHashMap();
440    Map<K, MapDifference.ValueDifference<V>> differences = newLinkedHashMap();
441    doDifference(left, right, valueEquivalence, onlyOnLeft, onlyOnRight, onBoth, differences);
442    return new MapDifferenceImpl<>(onlyOnLeft, onlyOnRight, onBoth, differences);
443  }
444
445  /**
446   * Computes the difference between two sorted maps, using the comparator of the left map, or
447   * {@code Ordering.natural()} if the left map uses the natural ordering of its elements. This
448   * difference is an immutable snapshot of the state of the maps at the time this method is called.
449   * It will never change, even if the maps change at a later time.
450   *
451   * <p>Since this method uses {@code TreeMap} instances internally, the keys of the right map must
452   * all compare as distinct according to the comparator of the left map.
453   *
454   * <p><b>Note:</b>If you only need to know whether two sorted maps have the same mappings, call
455   * {@code left.equals(right)} instead of this method.
456   *
457   * @param left the map to treat as the "left" map for purposes of comparison
458   * @param right the map to treat as the "right" map for purposes of comparison
459   * @return the difference between the two maps
460   * @since 11.0
461   */
462  public static <K, V> SortedMapDifference<K, V> difference(
463      SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right) {
464    checkNotNull(left);
465    checkNotNull(right);
466    Comparator<? super K> comparator = orNaturalOrder(left.comparator());
467    SortedMap<K, V> onlyOnLeft = Maps.newTreeMap(comparator);
468    SortedMap<K, V> onlyOnRight = Maps.newTreeMap(comparator);
469    onlyOnRight.putAll(right); // will whittle it down
470    SortedMap<K, V> onBoth = Maps.newTreeMap(comparator);
471    SortedMap<K, MapDifference.ValueDifference<V>> differences = Maps.newTreeMap(comparator);
472    doDifference(left, right, Equivalence.equals(), onlyOnLeft, onlyOnRight, onBoth, differences);
473    return new SortedMapDifferenceImpl<>(onlyOnLeft, onlyOnRight, onBoth, differences);
474  }
475
476  private static <K, V> void doDifference(
477      Map<? extends K, ? extends V> left,
478      Map<? extends K, ? extends V> right,
479      Equivalence<? super V> valueEquivalence,
480      Map<K, V> onlyOnLeft,
481      Map<K, V> onlyOnRight,
482      Map<K, V> onBoth,
483      Map<K, MapDifference.ValueDifference<V>> differences) {
484    for (Entry<? extends K, ? extends V> entry : left.entrySet()) {
485      K leftKey = entry.getKey();
486      V leftValue = entry.getValue();
487      if (right.containsKey(leftKey)) {
488        V rightValue = onlyOnRight.remove(leftKey);
489        if (valueEquivalence.equivalent(leftValue, rightValue)) {
490          onBoth.put(leftKey, leftValue);
491        } else {
492          differences.put(leftKey, ValueDifferenceImpl.create(leftValue, rightValue));
493        }
494      } else {
495        onlyOnLeft.put(leftKey, leftValue);
496      }
497    }
498  }
499
500  private static <K, V> Map<K, V> unmodifiableMap(Map<K, ? extends V> map) {
501    if (map instanceof SortedMap) {
502      return Collections.unmodifiableSortedMap((SortedMap<K, ? extends V>) map);
503    } else {
504      return Collections.unmodifiableMap(map);
505    }
506  }
507
508  static class MapDifferenceImpl<K, V> implements MapDifference<K, V> {
509    final Map<K, V> onlyOnLeft;
510    final Map<K, V> onlyOnRight;
511    final Map<K, V> onBoth;
512    final Map<K, ValueDifference<V>> differences;
513
514    MapDifferenceImpl(
515        Map<K, V> onlyOnLeft,
516        Map<K, V> onlyOnRight,
517        Map<K, V> onBoth,
518        Map<K, ValueDifference<V>> differences) {
519      this.onlyOnLeft = unmodifiableMap(onlyOnLeft);
520      this.onlyOnRight = unmodifiableMap(onlyOnRight);
521      this.onBoth = unmodifiableMap(onBoth);
522      this.differences = unmodifiableMap(differences);
523    }
524
525    @Override
526    public boolean areEqual() {
527      return onlyOnLeft.isEmpty() && onlyOnRight.isEmpty() && differences.isEmpty();
528    }
529
530    @Override
531    public Map<K, V> entriesOnlyOnLeft() {
532      return onlyOnLeft;
533    }
534
535    @Override
536    public Map<K, V> entriesOnlyOnRight() {
537      return onlyOnRight;
538    }
539
540    @Override
541    public Map<K, V> entriesInCommon() {
542      return onBoth;
543    }
544
545    @Override
546    public Map<K, ValueDifference<V>> entriesDiffering() {
547      return differences;
548    }
549
550    @Override
551    public boolean equals(Object object) {
552      if (object == this) {
553        return true;
554      }
555      if (object instanceof MapDifference) {
556        MapDifference<?, ?> other = (MapDifference<?, ?>) object;
557        return entriesOnlyOnLeft().equals(other.entriesOnlyOnLeft())
558            && entriesOnlyOnRight().equals(other.entriesOnlyOnRight())
559            && entriesInCommon().equals(other.entriesInCommon())
560            && entriesDiffering().equals(other.entriesDiffering());
561      }
562      return false;
563    }
564
565    @Override
566    public int hashCode() {
567      return Objects.hashCode(
568          entriesOnlyOnLeft(), entriesOnlyOnRight(), entriesInCommon(), entriesDiffering());
569    }
570
571    @Override
572    public String toString() {
573      if (areEqual()) {
574        return "equal";
575      }
576
577      StringBuilder result = new StringBuilder("not equal");
578      if (!onlyOnLeft.isEmpty()) {
579        result.append(": only on left=").append(onlyOnLeft);
580      }
581      if (!onlyOnRight.isEmpty()) {
582        result.append(": only on right=").append(onlyOnRight);
583      }
584      if (!differences.isEmpty()) {
585        result.append(": value differences=").append(differences);
586      }
587      return result.toString();
588    }
589  }
590
591  static class ValueDifferenceImpl<V> implements MapDifference.ValueDifference<V> {
592    @NullableDecl private final V left;
593    @NullableDecl private final V right;
594
595    static <V> ValueDifference<V> create(@NullableDecl V left, @NullableDecl V right) {
596      return new ValueDifferenceImpl<V>(left, right);
597    }
598
599    private ValueDifferenceImpl(@NullableDecl V left, @NullableDecl V right) {
600      this.left = left;
601      this.right = right;
602    }
603
604    @Override
605    public V leftValue() {
606      return left;
607    }
608
609    @Override
610    public V rightValue() {
611      return right;
612    }
613
614    @Override
615    public boolean equals(@NullableDecl Object object) {
616      if (object instanceof MapDifference.ValueDifference) {
617        MapDifference.ValueDifference<?> that = (MapDifference.ValueDifference<?>) object;
618        return Objects.equal(this.left, that.leftValue())
619            && Objects.equal(this.right, that.rightValue());
620      }
621      return false;
622    }
623
624    @Override
625    public int hashCode() {
626      return Objects.hashCode(left, right);
627    }
628
629    @Override
630    public String toString() {
631      return "(" + left + ", " + right + ")";
632    }
633  }
634
635  static class SortedMapDifferenceImpl<K, V> extends MapDifferenceImpl<K, V>
636      implements SortedMapDifference<K, V> {
637    SortedMapDifferenceImpl(
638        SortedMap<K, V> onlyOnLeft,
639        SortedMap<K, V> onlyOnRight,
640        SortedMap<K, V> onBoth,
641        SortedMap<K, ValueDifference<V>> differences) {
642      super(onlyOnLeft, onlyOnRight, onBoth, differences);
643    }
644
645    @Override
646    public SortedMap<K, ValueDifference<V>> entriesDiffering() {
647      return (SortedMap<K, ValueDifference<V>>) super.entriesDiffering();
648    }
649
650    @Override
651    public SortedMap<K, V> entriesInCommon() {
652      return (SortedMap<K, V>) super.entriesInCommon();
653    }
654
655    @Override
656    public SortedMap<K, V> entriesOnlyOnLeft() {
657      return (SortedMap<K, V>) super.entriesOnlyOnLeft();
658    }
659
660    @Override
661    public SortedMap<K, V> entriesOnlyOnRight() {
662      return (SortedMap<K, V>) super.entriesOnlyOnRight();
663    }
664  }
665
666  /**
667   * Returns the specified comparator if not null; otherwise returns {@code Ordering.natural()}.
668   * This method is an abomination of generics; the only purpose of this method is to contain the
669   * ugly type-casting in one place.
670   */
671  @SuppressWarnings("unchecked")
672  static <E> Comparator<? super E> orNaturalOrder(@NullableDecl Comparator<? super E> comparator) {
673    if (comparator != null) { // can't use ? : because of javac bug 5080917
674      return comparator;
675    }
676    return (Comparator<E>) Ordering.natural();
677  }
678
679  /**
680   * Returns a live {@link Map} view whose keys are the contents of {@code set} and whose values are
681   * computed on demand using {@code function}. To get an immutable <i>copy</i> instead, use {@link
682   * #toMap(Iterable, Function)}.
683   *
684   * <p>Specifically, for each {@code k} in the backing set, the returned map has an entry mapping
685   * {@code k} to {@code function.apply(k)}. The {@code keySet}, {@code values}, and {@code
686   * entrySet} views of the returned map iterate in the same order as the backing set.
687   *
688   * <p>Modifications to the backing set are read through to the returned map. The returned map
689   * supports removal operations if the backing set does. Removal operations write through to the
690   * backing set. The returned map does not support put operations.
691   *
692   * <p><b>Warning:</b> If the function rejects {@code null}, caution is required to make sure the
693   * set does not contain {@code null}, because the view cannot stop {@code null} from being added
694   * to the set.
695   *
696   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of key type {@code K},
697   * {@code k.equals(k2)} implies that {@code k2} is also of type {@code K}. Using a key type for
698   * which this may not hold, such as {@code ArrayList}, may risk a {@code ClassCastException} when
699   * calling methods on the resulting map view.
700   *
701   * @since 14.0
702   */
703  public static <K, V> Map<K, V> asMap(Set<K> set, Function<? super K, V> function) {
704    return new AsMapView<>(set, function);
705  }
706
707  /**
708   * Returns a view of the sorted set as a map, mapping keys from the set according to the specified
709   * function.
710   *
711   * <p>Specifically, for each {@code k} in the backing set, the returned map has an entry mapping
712   * {@code k} to {@code function.apply(k)}. The {@code keySet}, {@code values}, and {@code
713   * entrySet} views of the returned map iterate in the same order as the backing set.
714   *
715   * <p>Modifications to the backing set are read through to the returned map. The returned map
716   * supports removal operations if the backing set does. Removal operations write through to the
717   * backing set. The returned map does not support put operations.
718   *
719   * <p><b>Warning:</b> If the function rejects {@code null}, caution is required to make sure the
720   * set does not contain {@code null}, because the view cannot stop {@code null} from being added
721   * to the set.
722   *
723   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of key type {@code K},
724   * {@code k.equals(k2)} implies that {@code k2} is also of type {@code K}. Using a key type for
725   * which this may not hold, such as {@code ArrayList}, may risk a {@code ClassCastException} when
726   * calling methods on the resulting map view.
727   *
728   * @since 14.0
729   */
730  public static <K, V> SortedMap<K, V> asMap(SortedSet<K> set, Function<? super K, V> function) {
731    return new SortedAsMapView<>(set, function);
732  }
733
734  /**
735   * Returns a view of the navigable set as a map, mapping keys from the set according to the
736   * specified function.
737   *
738   * <p>Specifically, for each {@code k} in the backing set, the returned map has an entry mapping
739   * {@code k} to {@code function.apply(k)}. The {@code keySet}, {@code values}, and {@code
740   * entrySet} views of the returned map iterate in the same order as the backing set.
741   *
742   * <p>Modifications to the backing set are read through to the returned map. The returned map
743   * supports removal operations if the backing set does. Removal operations write through to the
744   * backing set. The returned map does not support put operations.
745   *
746   * <p><b>Warning:</b> If the function rejects {@code null}, caution is required to make sure the
747   * set does not contain {@code null}, because the view cannot stop {@code null} from being added
748   * to the set.
749   *
750   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of key type {@code K},
751   * {@code k.equals(k2)} implies that {@code k2} is also of type {@code K}. Using a key type for
752   * which this may not hold, such as {@code ArrayList}, may risk a {@code ClassCastException} when
753   * calling methods on the resulting map view.
754   *
755   * @since 14.0
756   */
757  @GwtIncompatible // NavigableMap
758  public static <K, V> NavigableMap<K, V> asMap(
759      NavigableSet<K> set, Function<? super K, V> function) {
760    return new NavigableAsMapView<>(set, function);
761  }
762
763  private static class AsMapView<K, V> extends ViewCachingAbstractMap<K, V> {
764
765    private final Set<K> set;
766    final Function<? super K, V> function;
767
768    Set<K> backingSet() {
769      return set;
770    }
771
772    AsMapView(Set<K> set, Function<? super K, V> function) {
773      this.set = checkNotNull(set);
774      this.function = checkNotNull(function);
775    }
776
777    @Override
778    public Set<K> createKeySet() {
779      return removeOnlySet(backingSet());
780    }
781
782    @Override
783    Collection<V> createValues() {
784      return Collections2.transform(set, function);
785    }
786
787    @Override
788    public int size() {
789      return backingSet().size();
790    }
791
792    @Override
793    public boolean containsKey(@NullableDecl Object key) {
794      return backingSet().contains(key);
795    }
796
797    @Override
798    public V get(@NullableDecl Object key) {
799      if (Collections2.safeContains(backingSet(), key)) {
800        @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
801        K k = (K) key;
802        return function.apply(k);
803      } else {
804        return null;
805      }
806    }
807
808    @Override
809    public V remove(@NullableDecl Object key) {
810      if (backingSet().remove(key)) {
811        @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
812        K k = (K) key;
813        return function.apply(k);
814      } else {
815        return null;
816      }
817    }
818
819    @Override
820    public void clear() {
821      backingSet().clear();
822    }
823
824    @Override
825    protected Set<Entry<K, V>> createEntrySet() {
826      @WeakOuter
827      class EntrySetImpl extends EntrySet<K, V> {
828        @Override
829        Map<K, V> map() {
830          return AsMapView.this;
831        }
832
833        @Override
834        public Iterator<Entry<K, V>> iterator() {
835          return asMapEntryIterator(backingSet(), function);
836        }
837      }
838      return new EntrySetImpl();
839    }
840  }
841
842  static <K, V> Iterator<Entry<K, V>> asMapEntryIterator(
843      Set<K> set, final Function<? super K, V> function) {
844    return new TransformedIterator<K, Entry<K, V>>(set.iterator()) {
845      @Override
846      Entry<K, V> transform(final K key) {
847        return immutableEntry(key, function.apply(key));
848      }
849    };
850  }
851
852  private static class SortedAsMapView<K, V> extends AsMapView<K, V> implements SortedMap<K, V> {
853
854    SortedAsMapView(SortedSet<K> set, Function<? super K, V> function) {
855      super(set, function);
856    }
857
858    @Override
859    SortedSet<K> backingSet() {
860      return (SortedSet<K>) super.backingSet();
861    }
862
863    @Override
864    public Comparator<? super K> comparator() {
865      return backingSet().comparator();
866    }
867
868    @Override
869    public Set<K> keySet() {
870      return removeOnlySortedSet(backingSet());
871    }
872
873    @Override
874    public SortedMap<K, V> subMap(K fromKey, K toKey) {
875      return asMap(backingSet().subSet(fromKey, toKey), function);
876    }
877
878    @Override
879    public SortedMap<K, V> headMap(K toKey) {
880      return asMap(backingSet().headSet(toKey), function);
881    }
882
883    @Override
884    public SortedMap<K, V> tailMap(K fromKey) {
885      return asMap(backingSet().tailSet(fromKey), function);
886    }
887
888    @Override
889    public K firstKey() {
890      return backingSet().first();
891    }
892
893    @Override
894    public K lastKey() {
895      return backingSet().last();
896    }
897  }
898
899  @GwtIncompatible // NavigableMap
900  private static final class NavigableAsMapView<K, V> extends AbstractNavigableMap<K, V> {
901    /*
902     * Using AbstractNavigableMap is simpler than extending SortedAsMapView and rewriting all the
903     * NavigableMap methods.
904     */
905
906    private final NavigableSet<K> set;
907    private final Function<? super K, V> function;
908
909    NavigableAsMapView(NavigableSet<K> ks, Function<? super K, V> vFunction) {
910      this.set = checkNotNull(ks);
911      this.function = checkNotNull(vFunction);
912    }
913
914    @Override
915    public NavigableMap<K, V> subMap(
916        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
917      return asMap(set.subSet(fromKey, fromInclusive, toKey, toInclusive), function);
918    }
919
920    @Override
921    public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
922      return asMap(set.headSet(toKey, inclusive), function);
923    }
924
925    @Override
926    public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
927      return asMap(set.tailSet(fromKey, inclusive), function);
928    }
929
930    @Override
931    public Comparator<? super K> comparator() {
932      return set.comparator();
933    }
934
935    @Override
936    @NullableDecl
937    public V get(@NullableDecl Object key) {
938      if (Collections2.safeContains(set, key)) {
939        @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
940        K k = (K) key;
941        return function.apply(k);
942      } else {
943        return null;
944      }
945    }
946
947    @Override
948    public void clear() {
949      set.clear();
950    }
951
952    @Override
953    Iterator<Entry<K, V>> entryIterator() {
954      return asMapEntryIterator(set, function);
955    }
956
957    @Override
958    Iterator<Entry<K, V>> descendingEntryIterator() {
959      return descendingMap().entrySet().iterator();
960    }
961
962    @Override
963    public NavigableSet<K> navigableKeySet() {
964      return removeOnlyNavigableSet(set);
965    }
966
967    @Override
968    public int size() {
969      return set.size();
970    }
971
972    @Override
973    public NavigableMap<K, V> descendingMap() {
974      return asMap(set.descendingSet(), function);
975    }
976  }
977
978  private static <E> Set<E> removeOnlySet(final Set<E> set) {
979    return new ForwardingSet<E>() {
980      @Override
981      protected Set<E> delegate() {
982        return set;
983      }
984
985      @Override
986      public boolean add(E element) {
987        throw new UnsupportedOperationException();
988      }
989
990      @Override
991      public boolean addAll(Collection<? extends E> es) {
992        throw new UnsupportedOperationException();
993      }
994    };
995  }
996
997  private static <E> SortedSet<E> removeOnlySortedSet(final SortedSet<E> set) {
998    return new ForwardingSortedSet<E>() {
999      @Override
1000      protected SortedSet<E> delegate() {
1001        return set;
1002      }
1003
1004      @Override
1005      public boolean add(E element) {
1006        throw new UnsupportedOperationException();
1007      }
1008
1009      @Override
1010      public boolean addAll(Collection<? extends E> es) {
1011        throw new UnsupportedOperationException();
1012      }
1013
1014      @Override
1015      public SortedSet<E> headSet(E toElement) {
1016        return removeOnlySortedSet(super.headSet(toElement));
1017      }
1018
1019      @Override
1020      public SortedSet<E> subSet(E fromElement, E toElement) {
1021        return removeOnlySortedSet(super.subSet(fromElement, toElement));
1022      }
1023
1024      @Override
1025      public SortedSet<E> tailSet(E fromElement) {
1026        return removeOnlySortedSet(super.tailSet(fromElement));
1027      }
1028    };
1029  }
1030
1031  @GwtIncompatible // NavigableSet
1032  private static <E> NavigableSet<E> removeOnlyNavigableSet(final NavigableSet<E> set) {
1033    return new ForwardingNavigableSet<E>() {
1034      @Override
1035      protected NavigableSet<E> delegate() {
1036        return set;
1037      }
1038
1039      @Override
1040      public boolean add(E element) {
1041        throw new UnsupportedOperationException();
1042      }
1043
1044      @Override
1045      public boolean addAll(Collection<? extends E> es) {
1046        throw new UnsupportedOperationException();
1047      }
1048
1049      @Override
1050      public SortedSet<E> headSet(E toElement) {
1051        return removeOnlySortedSet(super.headSet(toElement));
1052      }
1053
1054      @Override
1055      public NavigableSet<E> headSet(E toElement, boolean inclusive) {
1056        return removeOnlyNavigableSet(super.headSet(toElement, inclusive));
1057      }
1058
1059      @Override
1060      public SortedSet<E> subSet(E fromElement, E toElement) {
1061        return removeOnlySortedSet(super.subSet(fromElement, toElement));
1062      }
1063
1064      @Override
1065      public NavigableSet<E> subSet(
1066          E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
1067        return removeOnlyNavigableSet(
1068            super.subSet(fromElement, fromInclusive, toElement, toInclusive));
1069      }
1070
1071      @Override
1072      public SortedSet<E> tailSet(E fromElement) {
1073        return removeOnlySortedSet(super.tailSet(fromElement));
1074      }
1075
1076      @Override
1077      public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
1078        return removeOnlyNavigableSet(super.tailSet(fromElement, inclusive));
1079      }
1080
1081      @Override
1082      public NavigableSet<E> descendingSet() {
1083        return removeOnlyNavigableSet(super.descendingSet());
1084      }
1085    };
1086  }
1087
1088  /**
1089   * Returns an immutable map whose keys are the distinct elements of {@code keys} and whose value
1090   * for each key was computed by {@code valueFunction}. The map's iteration order is the order of
1091   * the first appearance of each key in {@code keys}.
1092   *
1093   * <p>When there are multiple instances of a key in {@code keys}, it is unspecified whether {@code
1094   * valueFunction} will be applied to more than one instance of that key and, if it is, which
1095   * result will be mapped to that key in the returned map.
1096   *
1097   * <p>If {@code keys} is a {@link Set}, a live view can be obtained instead of a copy using {@link
1098   * Maps#asMap(Set, Function)}.
1099   *
1100   * @throws NullPointerException if any element of {@code keys} is {@code null}, or if {@code
1101   *     valueFunction} produces {@code null} for any key
1102   * @since 14.0
1103   */
1104  public static <K, V> ImmutableMap<K, V> toMap(
1105      Iterable<K> keys, Function<? super K, V> valueFunction) {
1106    return toMap(keys.iterator(), valueFunction);
1107  }
1108
1109  /**
1110   * Returns an immutable map whose keys are the distinct elements of {@code keys} and whose value
1111   * for each key was computed by {@code valueFunction}. The map's iteration order is the order of
1112   * the first appearance of each key in {@code keys}.
1113   *
1114   * <p>When there are multiple instances of a key in {@code keys}, it is unspecified whether {@code
1115   * valueFunction} will be applied to more than one instance of that key and, if it is, which
1116   * result will be mapped to that key in the returned map.
1117   *
1118   * @throws NullPointerException if any element of {@code keys} is {@code null}, or if {@code
1119   *     valueFunction} produces {@code null} for any key
1120   * @since 14.0
1121   */
1122  public static <K, V> ImmutableMap<K, V> toMap(
1123      Iterator<K> keys, Function<? super K, V> valueFunction) {
1124    checkNotNull(valueFunction);
1125    // Using LHM instead of a builder so as not to fail on duplicate keys
1126    Map<K, V> builder = newLinkedHashMap();
1127    while (keys.hasNext()) {
1128      K key = keys.next();
1129      builder.put(key, valueFunction.apply(key));
1130    }
1131    return ImmutableMap.copyOf(builder);
1132  }
1133
1134  /**
1135   * Returns a map with the given {@code values}, indexed by keys derived from those values. In
1136   * other words, each input value produces an entry in the map whose key is the result of applying
1137   * {@code keyFunction} to that value. These entries appear in the same order as the input values.
1138   * Example usage:
1139   *
1140   * <pre>{@code
1141   * Color red = new Color("red", 255, 0, 0);
1142   * ...
1143   * ImmutableSet<Color> allColors = ImmutableSet.of(red, green, blue);
1144   *
1145   * Map<String, Color> colorForName =
1146   *     uniqueIndex(allColors, toStringFunction());
1147   * assertThat(colorForName).containsEntry("red", red);
1148   * }</pre>
1149   *
1150   * <p>If your index may associate multiple values with each key, use {@link
1151   * Multimaps#index(Iterable, Function) Multimaps.index}.
1152   *
1153   * @param values the values to use when constructing the {@code Map}
1154   * @param keyFunction the function used to produce the key for each value
1155   * @return a map mapping the result of evaluating the function {@code keyFunction} on each value
1156   *     in the input collection to that value
1157   * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one
1158   *     value in the input collection
1159   * @throws NullPointerException if any element of {@code values} is {@code null}, or if {@code
1160   *     keyFunction} produces {@code null} for any value
1161   */
1162  @CanIgnoreReturnValue
1163  public static <K, V> ImmutableMap<K, V> uniqueIndex(
1164      Iterable<V> values, Function<? super V, K> keyFunction) {
1165    // TODO(lowasser): consider presizing the builder if values is a Collection
1166    return uniqueIndex(values.iterator(), keyFunction);
1167  }
1168
1169  /**
1170   * Returns a map with the given {@code values}, indexed by keys derived from those values. In
1171   * other words, each input value produces an entry in the map whose key is the result of applying
1172   * {@code keyFunction} to that value. These entries appear in the same order as the input values.
1173   * Example usage:
1174   *
1175   * <pre>{@code
1176   * Color red = new Color("red", 255, 0, 0);
1177   * ...
1178   * Iterator<Color> allColors = ImmutableSet.of(red, green, blue).iterator();
1179   *
1180   * Map<String, Color> colorForName =
1181   *     uniqueIndex(allColors, toStringFunction());
1182   * assertThat(colorForName).containsEntry("red", red);
1183   * }</pre>
1184   *
1185   * <p>If your index may associate multiple values with each key, use {@link
1186   * Multimaps#index(Iterator, Function) Multimaps.index}.
1187   *
1188   * @param values the values to use when constructing the {@code Map}
1189   * @param keyFunction the function used to produce the key for each value
1190   * @return a map mapping the result of evaluating the function {@code keyFunction} on each value
1191   *     in the input collection to that value
1192   * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one
1193   *     value in the input collection
1194   * @throws NullPointerException if any element of {@code values} is {@code null}, or if {@code
1195   *     keyFunction} produces {@code null} for any value
1196   * @since 10.0
1197   */
1198  @CanIgnoreReturnValue
1199  public static <K, V> ImmutableMap<K, V> uniqueIndex(
1200      Iterator<V> values, Function<? super V, K> keyFunction) {
1201    checkNotNull(keyFunction);
1202    ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
1203    while (values.hasNext()) {
1204      V value = values.next();
1205      builder.put(keyFunction.apply(value), value);
1206    }
1207    try {
1208      return builder.build();
1209    } catch (IllegalArgumentException duplicateKeys) {
1210      throw new IllegalArgumentException(
1211          duplicateKeys.getMessage()
1212              + ". To index multiple values under a key, use Multimaps.index.");
1213    }
1214  }
1215
1216  /**
1217   * Creates an {@code ImmutableMap<String, String>} from a {@code Properties} instance. Properties
1218   * normally derive from {@code Map<Object, Object>}, but they typically contain strings, which is
1219   * awkward. This method lets you get a plain-old-{@code Map} out of a {@code Properties}.
1220   *
1221   * @param properties a {@code Properties} object to be converted
1222   * @return an immutable map containing all the entries in {@code properties}
1223   * @throws ClassCastException if any key in {@code Properties} is not a {@code String}
1224   * @throws NullPointerException if any key or value in {@code Properties} is null
1225   */
1226  @GwtIncompatible // java.util.Properties
1227  public static ImmutableMap<String, String> fromProperties(Properties properties) {
1228    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
1229
1230    for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements(); ) {
1231      String key = (String) e.nextElement();
1232      builder.put(key, properties.getProperty(key));
1233    }
1234
1235    return builder.build();
1236  }
1237
1238  /**
1239   * Returns an immutable map entry with the specified key and value. The {@link Entry#setValue}
1240   * operation throws an {@link UnsupportedOperationException}.
1241   *
1242   * <p>The returned entry is serializable.
1243   *
1244   * <p><b>Java 9 users:</b> consider using {@code java.util.Map.entry(key, value)} if the key and
1245   * value are non-null and the entry does not need to be serializable.
1246   *
1247   * @param key the key to be associated with the returned entry
1248   * @param value the value to be associated with the returned entry
1249   */
1250  @GwtCompatible(serializable = true)
1251  public static <K, V> Entry<K, V> immutableEntry(@NullableDecl K key, @NullableDecl V value) {
1252    return new ImmutableEntry<>(key, value);
1253  }
1254
1255  /**
1256   * Returns an unmodifiable view of the specified set of entries. The {@link Entry#setValue}
1257   * operation throws an {@link UnsupportedOperationException}, as do any operations that would
1258   * modify the returned set.
1259   *
1260   * @param entrySet the entries for which to return an unmodifiable view
1261   * @return an unmodifiable view of the entries
1262   */
1263  static <K, V> Set<Entry<K, V>> unmodifiableEntrySet(Set<Entry<K, V>> entrySet) {
1264    return new UnmodifiableEntrySet<>(Collections.unmodifiableSet(entrySet));
1265  }
1266
1267  /**
1268   * Returns an unmodifiable view of the specified map entry. The {@link Entry#setValue} operation
1269   * throws an {@link UnsupportedOperationException}. This also has the side-effect of redefining
1270   * {@code equals} to comply with the Entry contract, to avoid a possible nefarious implementation
1271   * of equals.
1272   *
1273   * @param entry the entry for which to return an unmodifiable view
1274   * @return an unmodifiable view of the entry
1275   */
1276  static <K, V> Entry<K, V> unmodifiableEntry(final Entry<? extends K, ? extends V> entry) {
1277    checkNotNull(entry);
1278    return new AbstractMapEntry<K, V>() {
1279      @Override
1280      public K getKey() {
1281        return entry.getKey();
1282      }
1283
1284      @Override
1285      public V getValue() {
1286        return entry.getValue();
1287      }
1288    };
1289  }
1290
1291  static <K, V> UnmodifiableIterator<Entry<K, V>> unmodifiableEntryIterator(
1292      final Iterator<Entry<K, V>> entryIterator) {
1293    return new UnmodifiableIterator<Entry<K, V>>() {
1294      @Override
1295      public boolean hasNext() {
1296        return entryIterator.hasNext();
1297      }
1298
1299      @Override
1300      public Entry<K, V> next() {
1301        return unmodifiableEntry(entryIterator.next());
1302      }
1303    };
1304  }
1305
1306  /** @see Multimaps#unmodifiableEntries */
1307  static class UnmodifiableEntries<K, V> extends ForwardingCollection<Entry<K, V>> {
1308    private final Collection<Entry<K, V>> entries;
1309
1310    UnmodifiableEntries(Collection<Entry<K, V>> entries) {
1311      this.entries = entries;
1312    }
1313
1314    @Override
1315    protected Collection<Entry<K, V>> delegate() {
1316      return entries;
1317    }
1318
1319    @Override
1320    public Iterator<Entry<K, V>> iterator() {
1321      return unmodifiableEntryIterator(entries.iterator());
1322    }
1323
1324    // See java.util.Collections.UnmodifiableEntrySet for details on attacks.
1325
1326    @Override
1327    public Object[] toArray() {
1328      return standardToArray();
1329    }
1330
1331    @Override
1332    public <T> T[] toArray(T[] array) {
1333      return standardToArray(array);
1334    }
1335  }
1336
1337  /** @see Maps#unmodifiableEntrySet(Set) */
1338  static class UnmodifiableEntrySet<K, V> extends UnmodifiableEntries<K, V>
1339      implements Set<Entry<K, V>> {
1340    UnmodifiableEntrySet(Set<Entry<K, V>> entries) {
1341      super(entries);
1342    }
1343
1344    // See java.util.Collections.UnmodifiableEntrySet for details on attacks.
1345
1346    @Override
1347    public boolean equals(@NullableDecl Object object) {
1348      return Sets.equalsImpl(this, object);
1349    }
1350
1351    @Override
1352    public int hashCode() {
1353      return Sets.hashCodeImpl(this);
1354    }
1355  }
1356
1357  /**
1358   * Returns a {@link Converter} that converts values using {@link BiMap#get bimap.get()}, and whose
1359   * inverse view converts values using {@link BiMap#inverse bimap.inverse()}{@code .get()}.
1360   *
1361   * <p>To use a plain {@link Map} as a {@link Function}, see {@link
1362   * com.google.common.base.Functions#forMap(Map)} or {@link
1363   * com.google.common.base.Functions#forMap(Map, Object)}.
1364   *
1365   * @since 16.0
1366   */
1367  public static <A, B> Converter<A, B> asConverter(final BiMap<A, B> bimap) {
1368    return new BiMapConverter<>(bimap);
1369  }
1370
1371  private static final class BiMapConverter<A, B> extends Converter<A, B> implements Serializable {
1372    private final BiMap<A, B> bimap;
1373
1374    BiMapConverter(BiMap<A, B> bimap) {
1375      this.bimap = checkNotNull(bimap);
1376    }
1377
1378    @Override
1379    protected B doForward(A a) {
1380      return convert(bimap, a);
1381    }
1382
1383    @Override
1384    protected A doBackward(B b) {
1385      return convert(bimap.inverse(), b);
1386    }
1387
1388    private static <X, Y> Y convert(BiMap<X, Y> bimap, X input) {
1389      Y output = bimap.get(input);
1390      checkArgument(output != null, "No non-null mapping present for input: %s", input);
1391      return output;
1392    }
1393
1394    @Override
1395    public boolean equals(@NullableDecl Object object) {
1396      if (object instanceof BiMapConverter) {
1397        BiMapConverter<?, ?> that = (BiMapConverter<?, ?>) object;
1398        return this.bimap.equals(that.bimap);
1399      }
1400      return false;
1401    }
1402
1403    @Override
1404    public int hashCode() {
1405      return bimap.hashCode();
1406    }
1407
1408    // There's really no good way to implement toString() without printing the entire BiMap, right?
1409    @Override
1410    public String toString() {
1411      return "Maps.asConverter(" + bimap + ")";
1412    }
1413
1414    private static final long serialVersionUID = 0L;
1415  }
1416
1417  /**
1418   * Returns a synchronized (thread-safe) bimap backed by the specified bimap. In order to guarantee
1419   * serial access, it is critical that <b>all</b> access to the backing bimap is accomplished
1420   * through the returned bimap.
1421   *
1422   * <p>It is imperative that the user manually synchronize on the returned map when accessing any
1423   * of its collection views:
1424   *
1425   * <pre>{@code
1426   * BiMap<Long, String> map = Maps.synchronizedBiMap(
1427   *     HashBiMap.<Long, String>create());
1428   * ...
1429   * Set<Long> set = map.keySet();  // Needn't be in synchronized block
1430   * ...
1431   * synchronized (map) {  // Synchronizing on map, not set!
1432   *   Iterator<Long> it = set.iterator(); // Must be in synchronized block
1433   *   while (it.hasNext()) {
1434   *     foo(it.next());
1435   *   }
1436   * }
1437   * }</pre>
1438   *
1439   * <p>Failure to follow this advice may result in non-deterministic behavior.
1440   *
1441   * <p>The returned bimap will be serializable if the specified bimap is serializable.
1442   *
1443   * @param bimap the bimap to be wrapped in a synchronized view
1444   * @return a synchronized view of the specified bimap
1445   */
1446  public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
1447    return Synchronized.biMap(bimap, null);
1448  }
1449
1450  /**
1451   * Returns an unmodifiable view of the specified bimap. This method allows modules to provide
1452   * users with "read-only" access to internal bimaps. Query operations on the returned bimap "read
1453   * through" to the specified bimap, and attempts to modify the returned map, whether direct or via
1454   * its collection views, result in an {@code UnsupportedOperationException}.
1455   *
1456   * <p>The returned bimap will be serializable if the specified bimap is serializable.
1457   *
1458   * @param bimap the bimap for which an unmodifiable view is to be returned
1459   * @return an unmodifiable view of the specified bimap
1460   */
1461  public static <K, V> BiMap<K, V> unmodifiableBiMap(BiMap<? extends K, ? extends V> bimap) {
1462    return new UnmodifiableBiMap<>(bimap, null);
1463  }
1464
1465  /** @see Maps#unmodifiableBiMap(BiMap) */
1466  private static class UnmodifiableBiMap<K, V> extends ForwardingMap<K, V>
1467      implements BiMap<K, V>, Serializable {
1468    final Map<K, V> unmodifiableMap;
1469    final BiMap<? extends K, ? extends V> delegate;
1470    @RetainedWith @NullableDecl BiMap<V, K> inverse;
1471    @NullableDecl transient Set<V> values;
1472
1473    UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate, @NullableDecl BiMap<V, K> inverse) {
1474      unmodifiableMap = Collections.unmodifiableMap(delegate);
1475      this.delegate = delegate;
1476      this.inverse = inverse;
1477    }
1478
1479    @Override
1480    protected Map<K, V> delegate() {
1481      return unmodifiableMap;
1482    }
1483
1484    @Override
1485    public V forcePut(K key, V value) {
1486      throw new UnsupportedOperationException();
1487    }
1488
1489    @Override
1490    public BiMap<V, K> inverse() {
1491      BiMap<V, K> result = inverse;
1492      return (result == null)
1493          ? inverse = new UnmodifiableBiMap<>(delegate.inverse(), this)
1494          : result;
1495    }
1496
1497    @Override
1498    public Set<V> values() {
1499      Set<V> result = values;
1500      return (result == null) ? values = Collections.unmodifiableSet(delegate.values()) : result;
1501    }
1502
1503    private static final long serialVersionUID = 0;
1504  }
1505
1506  /**
1507   * Returns a view of a map where each value is transformed by a function. All other properties of
1508   * the map, such as iteration order, are left intact. For example, the code:
1509   *
1510   * <pre>{@code
1511   * Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9);
1512   * Function<Integer, Double> sqrt =
1513   *     new Function<Integer, Double>() {
1514   *       public Double apply(Integer in) {
1515   *         return Math.sqrt((int) in);
1516   *       }
1517   *     };
1518   * Map<String, Double> transformed = Maps.transformValues(map, sqrt);
1519   * System.out.println(transformed);
1520   * }</pre>
1521   *
1522   * ... prints {@code {a=2.0, b=3.0}}.
1523   *
1524   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1525   * removal operations, and these are reflected in the underlying map.
1526   *
1527   * <p>It's acceptable for the underlying map to contain null keys, and even null values provided
1528   * that the function is capable of accepting null input. The transformed map might contain null
1529   * values, if the function sometimes gives a null result.
1530   *
1531   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1532   *
1533   * <p>The function is applied lazily, invoked when needed. This is necessary for the returned map
1534   * to be a view, but it means that the function will be applied many times for bulk operations
1535   * like {@link Map#containsValue} and {@code Map.toString()}. For this to perform well, {@code
1536   * function} should be fast. To avoid lazy evaluation when the returned map doesn't need to be a
1537   * view, copy the returned map into a new map of your choosing.
1538   */
1539  public static <K, V1, V2> Map<K, V2> transformValues(
1540      Map<K, V1> fromMap, Function<? super V1, V2> function) {
1541    return transformEntries(fromMap, asEntryTransformer(function));
1542  }
1543
1544  /**
1545   * Returns a view of a sorted map where each value is transformed by a function. All other
1546   * properties of the map, such as iteration order, are left intact. For example, the code:
1547   *
1548   * <pre>{@code
1549   * SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
1550   * Function<Integer, Double> sqrt =
1551   *     new Function<Integer, Double>() {
1552   *       public Double apply(Integer in) {
1553   *         return Math.sqrt((int) in);
1554   *       }
1555   *     };
1556   * SortedMap<String, Double> transformed =
1557   *      Maps.transformValues(map, sqrt);
1558   * System.out.println(transformed);
1559   * }</pre>
1560   *
1561   * ... prints {@code {a=2.0, b=3.0}}.
1562   *
1563   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1564   * removal operations, and these are reflected in the underlying map.
1565   *
1566   * <p>It's acceptable for the underlying map to contain null keys, and even null values provided
1567   * that the function is capable of accepting null input. The transformed map might contain null
1568   * values, if the function sometimes gives a null result.
1569   *
1570   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1571   *
1572   * <p>The function is applied lazily, invoked when needed. This is necessary for the returned map
1573   * to be a view, but it means that the function will be applied many times for bulk operations
1574   * like {@link Map#containsValue} and {@code Map.toString()}. For this to perform well, {@code
1575   * function} should be fast. To avoid lazy evaluation when the returned map doesn't need to be a
1576   * view, copy the returned map into a new map of your choosing.
1577   *
1578   * @since 11.0
1579   */
1580  public static <K, V1, V2> SortedMap<K, V2> transformValues(
1581      SortedMap<K, V1> fromMap, Function<? super V1, V2> function) {
1582    return transformEntries(fromMap, asEntryTransformer(function));
1583  }
1584
1585  /**
1586   * Returns a view of a navigable map where each value is transformed by a function. All other
1587   * properties of the map, such as iteration order, are left intact. For example, the code:
1588   *
1589   * <pre>{@code
1590   * NavigableMap<String, Integer> map = Maps.newTreeMap();
1591   * map.put("a", 4);
1592   * map.put("b", 9);
1593   * Function<Integer, Double> sqrt =
1594   *     new Function<Integer, Double>() {
1595   *       public Double apply(Integer in) {
1596   *         return Math.sqrt((int) in);
1597   *       }
1598   *     };
1599   * NavigableMap<String, Double> transformed =
1600   *      Maps.transformNavigableValues(map, sqrt);
1601   * System.out.println(transformed);
1602   * }</pre>
1603   *
1604   * ... prints {@code {a=2.0, b=3.0}}.
1605   *
1606   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1607   * removal operations, and these are reflected in the underlying map.
1608   *
1609   * <p>It's acceptable for the underlying map to contain null keys, and even null values provided
1610   * that the function is capable of accepting null input. The transformed map might contain null
1611   * values, if the function sometimes gives a null result.
1612   *
1613   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1614   *
1615   * <p>The function is applied lazily, invoked when needed. This is necessary for the returned map
1616   * to be a view, but it means that the function will be applied many times for bulk operations
1617   * like {@link Map#containsValue} and {@code Map.toString()}. For this to perform well, {@code
1618   * function} should be fast. To avoid lazy evaluation when the returned map doesn't need to be a
1619   * view, copy the returned map into a new map of your choosing.
1620   *
1621   * @since 13.0
1622   */
1623  @GwtIncompatible // NavigableMap
1624  public static <K, V1, V2> NavigableMap<K, V2> transformValues(
1625      NavigableMap<K, V1> fromMap, Function<? super V1, V2> function) {
1626    return transformEntries(fromMap, asEntryTransformer(function));
1627  }
1628
1629  /**
1630   * Returns a view of a map whose values are derived from the original map's entries. In contrast
1631   * to {@link #transformValues}, this method's entry-transformation logic may depend on the key as
1632   * well as the value.
1633   *
1634   * <p>All other properties of the transformed map, such as iteration order, are left intact. For
1635   * example, the code:
1636   *
1637   * <pre>{@code
1638   * Map<String, Boolean> options =
1639   *     ImmutableMap.of("verbose", true, "sort", false);
1640   * EntryTransformer<String, Boolean, String> flagPrefixer =
1641   *     new EntryTransformer<String, Boolean, String>() {
1642   *       public String transformEntry(String key, Boolean value) {
1643   *         return value ? key : "no" + key;
1644   *       }
1645   *     };
1646   * Map<String, String> transformed =
1647   *     Maps.transformEntries(options, flagPrefixer);
1648   * System.out.println(transformed);
1649   * }</pre>
1650   *
1651   * ... prints {@code {verbose=verbose, sort=nosort}}.
1652   *
1653   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1654   * removal operations, and these are reflected in the underlying map.
1655   *
1656   * <p>It's acceptable for the underlying map to contain null keys and null values provided that
1657   * the transformer is capable of accepting null inputs. The transformed map might contain null
1658   * values if the transformer sometimes gives a null result.
1659   *
1660   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1661   *
1662   * <p>The transformer is applied lazily, invoked when needed. This is necessary for the returned
1663   * map to be a view, but it means that the transformer will be applied many times for bulk
1664   * operations like {@link Map#containsValue} and {@link Object#toString}. For this to perform
1665   * well, {@code transformer} should be fast. To avoid lazy evaluation when the returned map
1666   * doesn't need to be a view, copy the returned map into a new map of your choosing.
1667   *
1668   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of {@code
1669   * EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
1670   * type {@code K}. Using an {@code EntryTransformer} key type for which this may not hold, such as
1671   * {@code ArrayList}, may risk a {@code ClassCastException} when calling methods on the
1672   * transformed map.
1673   *
1674   * @since 7.0
1675   */
1676  public static <K, V1, V2> Map<K, V2> transformEntries(
1677      Map<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1678    return new TransformedEntriesMap<>(fromMap, transformer);
1679  }
1680
1681  /**
1682   * Returns a view of a sorted map whose values are derived from the original sorted map's entries.
1683   * In contrast to {@link #transformValues}, this method's entry-transformation logic may depend on
1684   * the key as well as the value.
1685   *
1686   * <p>All other properties of the transformed map, such as iteration order, are left intact. For
1687   * example, the code:
1688   *
1689   * <pre>{@code
1690   * Map<String, Boolean> options =
1691   *     ImmutableSortedMap.of("verbose", true, "sort", false);
1692   * EntryTransformer<String, Boolean, String> flagPrefixer =
1693   *     new EntryTransformer<String, Boolean, String>() {
1694   *       public String transformEntry(String key, Boolean value) {
1695   *         return value ? key : "yes" + key;
1696   *       }
1697   *     };
1698   * SortedMap<String, String> transformed =
1699   *     Maps.transformEntries(options, flagPrefixer);
1700   * System.out.println(transformed);
1701   * }</pre>
1702   *
1703   * ... prints {@code {sort=yessort, verbose=verbose}}.
1704   *
1705   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1706   * removal operations, and these are reflected in the underlying map.
1707   *
1708   * <p>It's acceptable for the underlying map to contain null keys and null values provided that
1709   * the transformer is capable of accepting null inputs. The transformed map might contain null
1710   * values if the transformer sometimes gives a null result.
1711   *
1712   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1713   *
1714   * <p>The transformer is applied lazily, invoked when needed. This is necessary for the returned
1715   * map to be a view, but it means that the transformer will be applied many times for bulk
1716   * operations like {@link Map#containsValue} and {@link Object#toString}. For this to perform
1717   * well, {@code transformer} should be fast. To avoid lazy evaluation when the returned map
1718   * doesn't need to be a view, copy the returned map into a new map of your choosing.
1719   *
1720   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of {@code
1721   * EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
1722   * type {@code K}. Using an {@code EntryTransformer} key type for which this may not hold, such as
1723   * {@code ArrayList}, may risk a {@code ClassCastException} when calling methods on the
1724   * transformed map.
1725   *
1726   * @since 11.0
1727   */
1728  public static <K, V1, V2> SortedMap<K, V2> transformEntries(
1729      SortedMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1730    return new TransformedEntriesSortedMap<>(fromMap, transformer);
1731  }
1732
1733  /**
1734   * Returns a view of a navigable map whose values are derived from the original navigable map's
1735   * entries. In contrast to {@link #transformValues}, this method's entry-transformation logic may
1736   * depend on the key as well as the value.
1737   *
1738   * <p>All other properties of the transformed map, such as iteration order, are left intact. For
1739   * example, the code:
1740   *
1741   * <pre>{@code
1742   * NavigableMap<String, Boolean> options = Maps.newTreeMap();
1743   * options.put("verbose", false);
1744   * options.put("sort", true);
1745   * EntryTransformer<String, Boolean, String> flagPrefixer =
1746   *     new EntryTransformer<String, Boolean, String>() {
1747   *       public String transformEntry(String key, Boolean value) {
1748   *         return value ? key : ("yes" + key);
1749   *       }
1750   *     };
1751   * NavigableMap<String, String> transformed =
1752   *     LabsMaps.transformNavigableEntries(options, flagPrefixer);
1753   * System.out.println(transformed);
1754   * }</pre>
1755   *
1756   * ... prints {@code {sort=yessort, verbose=verbose}}.
1757   *
1758   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1759   * removal operations, and these are reflected in the underlying map.
1760   *
1761   * <p>It's acceptable for the underlying map to contain null keys and null values provided that
1762   * the transformer is capable of accepting null inputs. The transformed map might contain null
1763   * values if the transformer sometimes gives a null result.
1764   *
1765   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1766   *
1767   * <p>The transformer is applied lazily, invoked when needed. This is necessary for the returned
1768   * map to be a view, but it means that the transformer will be applied many times for bulk
1769   * operations like {@link Map#containsValue} and {@link Object#toString}. For this to perform
1770   * well, {@code transformer} should be fast. To avoid lazy evaluation when the returned map
1771   * doesn't need to be a view, copy the returned map into a new map of your choosing.
1772   *
1773   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of {@code
1774   * EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
1775   * type {@code K}. Using an {@code EntryTransformer} key type for which this may not hold, such as
1776   * {@code ArrayList}, may risk a {@code ClassCastException} when calling methods on the
1777   * transformed map.
1778   *
1779   * @since 13.0
1780   */
1781  @GwtIncompatible // NavigableMap
1782  public static <K, V1, V2> NavigableMap<K, V2> transformEntries(
1783      NavigableMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1784    return new TransformedEntriesNavigableMap<>(fromMap, transformer);
1785  }
1786
1787  /**
1788   * A transformation of the value of a key-value pair, using both key and value as inputs. To apply
1789   * the transformation to a map, use {@link Maps#transformEntries(Map, EntryTransformer)}.
1790   *
1791   * @param <K> the key type of the input and output entries
1792   * @param <V1> the value type of the input entry
1793   * @param <V2> the value type of the output entry
1794   * @since 7.0
1795   */
1796  public interface EntryTransformer<K, V1, V2> {
1797    /**
1798     * Determines an output value based on a key-value pair. This method is <i>generally
1799     * expected</i>, but not absolutely required, to have the following properties:
1800     *
1801     * <ul>
1802     *   <li>Its execution does not cause any observable side effects.
1803     *   <li>The computation is <i>consistent with equals</i>; that is, {@link Objects#equal
1804     *       Objects.equal}{@code (k1, k2) &&} {@link Objects#equal}{@code (v1, v2)} implies that
1805     *       {@code Objects.equal(transformer.transform(k1, v1), transformer.transform(k2, v2))}.
1806     * </ul>
1807     *
1808     * @throws NullPointerException if the key or value is null and this transformer does not accept
1809     *     null arguments
1810     */
1811    V2 transformEntry(@NullableDecl K key, @NullableDecl V1 value);
1812  }
1813
1814  /** Views a function as an entry transformer that ignores the entry key. */
1815  static <K, V1, V2> EntryTransformer<K, V1, V2> asEntryTransformer(
1816      final Function<? super V1, V2> function) {
1817    checkNotNull(function);
1818    return new EntryTransformer<K, V1, V2>() {
1819      @Override
1820      public V2 transformEntry(K key, V1 value) {
1821        return function.apply(value);
1822      }
1823    };
1824  }
1825
1826  static <K, V1, V2> Function<V1, V2> asValueToValueFunction(
1827      final EntryTransformer<? super K, V1, V2> transformer, final K key) {
1828    checkNotNull(transformer);
1829    return new Function<V1, V2>() {
1830      @Override
1831      public V2 apply(@NullableDecl V1 v1) {
1832        return transformer.transformEntry(key, v1);
1833      }
1834    };
1835  }
1836
1837  /** Views an entry transformer as a function from {@code Entry} to values. */
1838  static <K, V1, V2> Function<Entry<K, V1>, V2> asEntryToValueFunction(
1839      final EntryTransformer<? super K, ? super V1, V2> transformer) {
1840    checkNotNull(transformer);
1841    return new Function<Entry<K, V1>, V2>() {
1842      @Override
1843      public V2 apply(Entry<K, V1> entry) {
1844        return transformer.transformEntry(entry.getKey(), entry.getValue());
1845      }
1846    };
1847  }
1848
1849  /** Returns a view of an entry transformed by the specified transformer. */
1850  static <V2, K, V1> Entry<K, V2> transformEntry(
1851      final EntryTransformer<? super K, ? super V1, V2> transformer, final Entry<K, V1> entry) {
1852    checkNotNull(transformer);
1853    checkNotNull(entry);
1854    return new AbstractMapEntry<K, V2>() {
1855      @Override
1856      public K getKey() {
1857        return entry.getKey();
1858      }
1859
1860      @Override
1861      public V2 getValue() {
1862        return transformer.transformEntry(entry.getKey(), entry.getValue());
1863      }
1864    };
1865  }
1866
1867  /** Views an entry transformer as a function from entries to entries. */
1868  static <K, V1, V2> Function<Entry<K, V1>, Entry<K, V2>> asEntryToEntryFunction(
1869      final EntryTransformer<? super K, ? super V1, V2> transformer) {
1870    checkNotNull(transformer);
1871    return new Function<Entry<K, V1>, Entry<K, V2>>() {
1872      @Override
1873      public Entry<K, V2> apply(final Entry<K, V1> entry) {
1874        return transformEntry(transformer, entry);
1875      }
1876    };
1877  }
1878
1879  static class TransformedEntriesMap<K, V1, V2> extends IteratorBasedAbstractMap<K, V2> {
1880    final Map<K, V1> fromMap;
1881    final EntryTransformer<? super K, ? super V1, V2> transformer;
1882
1883    TransformedEntriesMap(
1884        Map<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1885      this.fromMap = checkNotNull(fromMap);
1886      this.transformer = checkNotNull(transformer);
1887    }
1888
1889    @Override
1890    public int size() {
1891      return fromMap.size();
1892    }
1893
1894    @Override
1895    public boolean containsKey(Object key) {
1896      return fromMap.containsKey(key);
1897    }
1898
1899    // safe as long as the user followed the <b>Warning</b> in the javadoc
1900    @SuppressWarnings("unchecked")
1901    @Override
1902    public V2 get(Object key) {
1903      V1 value = fromMap.get(key);
1904      return (value != null || fromMap.containsKey(key))
1905          ? transformer.transformEntry((K) key, value)
1906          : null;
1907    }
1908
1909    // safe as long as the user followed the <b>Warning</b> in the javadoc
1910    @SuppressWarnings("unchecked")
1911    @Override
1912    public V2 remove(Object key) {
1913      return fromMap.containsKey(key)
1914          ? transformer.transformEntry((K) key, fromMap.remove(key))
1915          : null;
1916    }
1917
1918    @Override
1919    public void clear() {
1920      fromMap.clear();
1921    }
1922
1923    @Override
1924    public Set<K> keySet() {
1925      return fromMap.keySet();
1926    }
1927
1928    @Override
1929    Iterator<Entry<K, V2>> entryIterator() {
1930      return Iterators.transform(
1931          fromMap.entrySet().iterator(), Maps.<K, V1, V2>asEntryToEntryFunction(transformer));
1932    }
1933
1934    @Override
1935    public Collection<V2> values() {
1936      return new Values<>(this);
1937    }
1938  }
1939
1940  static class TransformedEntriesSortedMap<K, V1, V2> extends TransformedEntriesMap<K, V1, V2>
1941      implements SortedMap<K, V2> {
1942
1943    protected SortedMap<K, V1> fromMap() {
1944      return (SortedMap<K, V1>) fromMap;
1945    }
1946
1947    TransformedEntriesSortedMap(
1948        SortedMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1949      super(fromMap, transformer);
1950    }
1951
1952    @Override
1953    public Comparator<? super K> comparator() {
1954      return fromMap().comparator();
1955    }
1956
1957    @Override
1958    public K firstKey() {
1959      return fromMap().firstKey();
1960    }
1961
1962    @Override
1963    public SortedMap<K, V2> headMap(K toKey) {
1964      return transformEntries(fromMap().headMap(toKey), transformer);
1965    }
1966
1967    @Override
1968    public K lastKey() {
1969      return fromMap().lastKey();
1970    }
1971
1972    @Override
1973    public SortedMap<K, V2> subMap(K fromKey, K toKey) {
1974      return transformEntries(fromMap().subMap(fromKey, toKey), transformer);
1975    }
1976
1977    @Override
1978    public SortedMap<K, V2> tailMap(K fromKey) {
1979      return transformEntries(fromMap().tailMap(fromKey), transformer);
1980    }
1981  }
1982
1983  @GwtIncompatible // NavigableMap
1984  private static class TransformedEntriesNavigableMap<K, V1, V2>
1985      extends TransformedEntriesSortedMap<K, V1, V2> implements NavigableMap<K, V2> {
1986
1987    TransformedEntriesNavigableMap(
1988        NavigableMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1989      super(fromMap, transformer);
1990    }
1991
1992    @Override
1993    public Entry<K, V2> ceilingEntry(K key) {
1994      return transformEntry(fromMap().ceilingEntry(key));
1995    }
1996
1997    @Override
1998    public K ceilingKey(K key) {
1999      return fromMap().ceilingKey(key);
2000    }
2001
2002    @Override
2003    public NavigableSet<K> descendingKeySet() {
2004      return fromMap().descendingKeySet();
2005    }
2006
2007    @Override
2008    public NavigableMap<K, V2> descendingMap() {
2009      return transformEntries(fromMap().descendingMap(), transformer);
2010    }
2011
2012    @Override
2013    public Entry<K, V2> firstEntry() {
2014      return transformEntry(fromMap().firstEntry());
2015    }
2016
2017    @Override
2018    public Entry<K, V2> floorEntry(K key) {
2019      return transformEntry(fromMap().floorEntry(key));
2020    }
2021
2022    @Override
2023    public K floorKey(K key) {
2024      return fromMap().floorKey(key);
2025    }
2026
2027    @Override
2028    public NavigableMap<K, V2> headMap(K toKey) {
2029      return headMap(toKey, false);
2030    }
2031
2032    @Override
2033    public NavigableMap<K, V2> headMap(K toKey, boolean inclusive) {
2034      return transformEntries(fromMap().headMap(toKey, inclusive), transformer);
2035    }
2036
2037    @Override
2038    public Entry<K, V2> higherEntry(K key) {
2039      return transformEntry(fromMap().higherEntry(key));
2040    }
2041
2042    @Override
2043    public K higherKey(K key) {
2044      return fromMap().higherKey(key);
2045    }
2046
2047    @Override
2048    public Entry<K, V2> lastEntry() {
2049      return transformEntry(fromMap().lastEntry());
2050    }
2051
2052    @Override
2053    public Entry<K, V2> lowerEntry(K key) {
2054      return transformEntry(fromMap().lowerEntry(key));
2055    }
2056
2057    @Override
2058    public K lowerKey(K key) {
2059      return fromMap().lowerKey(key);
2060    }
2061
2062    @Override
2063    public NavigableSet<K> navigableKeySet() {
2064      return fromMap().navigableKeySet();
2065    }
2066
2067    @Override
2068    public Entry<K, V2> pollFirstEntry() {
2069      return transformEntry(fromMap().pollFirstEntry());
2070    }
2071
2072    @Override
2073    public Entry<K, V2> pollLastEntry() {
2074      return transformEntry(fromMap().pollLastEntry());
2075    }
2076
2077    @Override
2078    public NavigableMap<K, V2> subMap(
2079        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
2080      return transformEntries(
2081          fromMap().subMap(fromKey, fromInclusive, toKey, toInclusive), transformer);
2082    }
2083
2084    @Override
2085    public NavigableMap<K, V2> subMap(K fromKey, K toKey) {
2086      return subMap(fromKey, true, toKey, false);
2087    }
2088
2089    @Override
2090    public NavigableMap<K, V2> tailMap(K fromKey) {
2091      return tailMap(fromKey, true);
2092    }
2093
2094    @Override
2095    public NavigableMap<K, V2> tailMap(K fromKey, boolean inclusive) {
2096      return transformEntries(fromMap().tailMap(fromKey, inclusive), transformer);
2097    }
2098
2099    @NullableDecl
2100    private Entry<K, V2> transformEntry(@NullableDecl Entry<K, V1> entry) {
2101      return (entry == null) ? null : Maps.transformEntry(transformer, entry);
2102    }
2103
2104    @Override
2105    protected NavigableMap<K, V1> fromMap() {
2106      return (NavigableMap<K, V1>) super.fromMap();
2107    }
2108  }
2109
2110  static <K> Predicate<Entry<K, ?>> keyPredicateOnEntries(Predicate<? super K> keyPredicate) {
2111    return compose(keyPredicate, Maps.<K>keyFunction());
2112  }
2113
2114  static <V> Predicate<Entry<?, V>> valuePredicateOnEntries(Predicate<? super V> valuePredicate) {
2115    return compose(valuePredicate, Maps.<V>valueFunction());
2116  }
2117
2118  /**
2119   * Returns a map containing the mappings in {@code unfiltered} whose keys satisfy a predicate. The
2120   * returned map is a live view of {@code unfiltered}; changes to one affect the other.
2121   *
2122   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2123   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2124   * and its views. When given a key that doesn't satisfy the predicate, the map's {@code put()} and
2125   * {@code putAll()} methods throw an {@link IllegalArgumentException}.
2126   *
2127   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2128   * or its views, only mappings whose keys satisfy the filter will be removed from the underlying
2129   * map.
2130   *
2131   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2132   *
2133   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2134   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2135   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2136   *
2137   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, as documented at
2138   * {@link Predicate#apply}. Do not provide a predicate such as {@code
2139   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2140   */
2141  public static <K, V> Map<K, V> filterKeys(
2142      Map<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2143    checkNotNull(keyPredicate);
2144    Predicate<Entry<K, ?>> entryPredicate = keyPredicateOnEntries(keyPredicate);
2145    return (unfiltered instanceof AbstractFilteredMap)
2146        ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate)
2147        : new FilteredKeyMap<K, V>(checkNotNull(unfiltered), keyPredicate, entryPredicate);
2148  }
2149
2150  /**
2151   * Returns a sorted map containing the mappings in {@code unfiltered} whose keys satisfy a
2152   * predicate. The returned map is a live view of {@code unfiltered}; changes to one affect the
2153   * other.
2154   *
2155   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2156   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2157   * and its views. When given a key that doesn't satisfy the predicate, the map's {@code put()} and
2158   * {@code putAll()} methods throw an {@link IllegalArgumentException}.
2159   *
2160   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2161   * or its views, only mappings whose keys satisfy the filter will be removed from the underlying
2162   * map.
2163   *
2164   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2165   *
2166   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2167   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2168   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2169   *
2170   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, as documented at
2171   * {@link Predicate#apply}. Do not provide a predicate such as {@code
2172   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2173   *
2174   * @since 11.0
2175   */
2176  public static <K, V> SortedMap<K, V> filterKeys(
2177      SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2178    // TODO(lowasser): Return a subclass of Maps.FilteredKeyMap for slightly better
2179    // performance.
2180    return filterEntries(unfiltered, Maps.<K>keyPredicateOnEntries(keyPredicate));
2181  }
2182
2183  /**
2184   * Returns a navigable map containing the mappings in {@code unfiltered} whose keys satisfy a
2185   * predicate. The returned map is a live view of {@code unfiltered}; changes to one affect the
2186   * other.
2187   *
2188   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2189   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2190   * and its views. When given a key that doesn't satisfy the predicate, the map's {@code put()} and
2191   * {@code putAll()} methods throw an {@link IllegalArgumentException}.
2192   *
2193   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2194   * or its views, only mappings whose keys satisfy the filter will be removed from the underlying
2195   * map.
2196   *
2197   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2198   *
2199   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2200   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2201   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2202   *
2203   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, as documented at
2204   * {@link Predicate#apply}. Do not provide a predicate such as {@code
2205   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2206   *
2207   * @since 14.0
2208   */
2209  @GwtIncompatible // NavigableMap
2210  public static <K, V> NavigableMap<K, V> filterKeys(
2211      NavigableMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2212    // TODO(lowasser): Return a subclass of Maps.FilteredKeyMap for slightly better
2213    // performance.
2214    return filterEntries(unfiltered, Maps.<K>keyPredicateOnEntries(keyPredicate));
2215  }
2216
2217  /**
2218   * Returns a bimap containing the mappings in {@code unfiltered} whose keys satisfy a predicate.
2219   * The returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
2220   *
2221   * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2222   * iterators that don't support {@code remove()}, but all other methods are supported by the bimap
2223   * and its views. When given a key that doesn't satisfy the predicate, the bimap's {@code put()},
2224   * {@code forcePut()} and {@code putAll()} methods throw an {@link IllegalArgumentException}.
2225   *
2226   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2227   * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
2228   * bimap.
2229   *
2230   * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2231   *
2232   * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every key in
2233   * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i>
2234   * needed, it may be faster to copy the filtered bimap and use the copy.
2235   *
2236   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as documented
2237   * at {@link Predicate#apply}.
2238   *
2239   * @since 14.0
2240   */
2241  public static <K, V> BiMap<K, V> filterKeys(
2242      BiMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2243    checkNotNull(keyPredicate);
2244    return filterEntries(unfiltered, Maps.<K>keyPredicateOnEntries(keyPredicate));
2245  }
2246
2247  /**
2248   * Returns a map containing the mappings in {@code unfiltered} whose values satisfy a predicate.
2249   * The returned map is a live view of {@code unfiltered}; changes to one affect the other.
2250   *
2251   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2252   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2253   * and its views. When given a value that doesn't satisfy the predicate, the map's {@code put()},
2254   * {@code putAll()}, and {@link Entry#setValue} methods throw an {@link IllegalArgumentException}.
2255   *
2256   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2257   * or its views, only mappings whose values satisfy the filter will be removed from the underlying
2258   * map.
2259   *
2260   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2261   *
2262   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2263   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2264   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2265   *
2266   * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with equals</i>, as documented
2267   * at {@link Predicate#apply}. Do not provide a predicate such as {@code
2268   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2269   */
2270  public static <K, V> Map<K, V> filterValues(
2271      Map<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2272    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2273  }
2274
2275  /**
2276   * Returns a sorted map containing the mappings in {@code unfiltered} whose values satisfy a
2277   * predicate. The returned map is a live view of {@code unfiltered}; changes to one affect the
2278   * other.
2279   *
2280   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2281   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2282   * and its views. When given a value that doesn't satisfy the predicate, the map's {@code put()},
2283   * {@code putAll()}, and {@link Entry#setValue} methods throw an {@link IllegalArgumentException}.
2284   *
2285   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2286   * or its views, only mappings whose values satisfy the filter will be removed from the underlying
2287   * map.
2288   *
2289   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2290   *
2291   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2292   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2293   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2294   *
2295   * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with equals</i>, as documented
2296   * at {@link Predicate#apply}. Do not provide a predicate such as {@code
2297   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2298   *
2299   * @since 11.0
2300   */
2301  public static <K, V> SortedMap<K, V> filterValues(
2302      SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2303    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2304  }
2305
2306  /**
2307   * Returns a navigable map containing the mappings in {@code unfiltered} whose values satisfy a
2308   * predicate. The returned map is a live view of {@code unfiltered}; changes to one affect the
2309   * other.
2310   *
2311   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2312   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2313   * and its views. When given a value that doesn't satisfy the predicate, the map's {@code put()},
2314   * {@code putAll()}, and {@link Entry#setValue} methods throw an {@link IllegalArgumentException}.
2315   *
2316   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2317   * or its views, only mappings whose values satisfy the filter will be removed from the underlying
2318   * map.
2319   *
2320   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2321   *
2322   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2323   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2324   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2325   *
2326   * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with equals</i>, as documented
2327   * at {@link Predicate#apply}. Do not provide a predicate such as {@code
2328   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2329   *
2330   * @since 14.0
2331   */
2332  @GwtIncompatible // NavigableMap
2333  public static <K, V> NavigableMap<K, V> filterValues(
2334      NavigableMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2335    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2336  }
2337
2338  /**
2339   * Returns a bimap containing the mappings in {@code unfiltered} whose values satisfy a predicate.
2340   * The returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
2341   *
2342   * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2343   * iterators that don't support {@code remove()}, but all other methods are supported by the bimap
2344   * and its views. When given a value that doesn't satisfy the predicate, the bimap's {@code
2345   * put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link
2346   * IllegalArgumentException}. Similarly, the map's entries have a {@link Entry#setValue} method
2347   * that throws an {@link IllegalArgumentException} when the provided value doesn't satisfy the
2348   * predicate.
2349   *
2350   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2351   * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
2352   * bimap.
2353   *
2354   * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2355   *
2356   * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every value in
2357   * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i>
2358   * needed, it may be faster to copy the filtered bimap and use the copy.
2359   *
2360   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as documented
2361   * at {@link Predicate#apply}.
2362   *
2363   * @since 14.0
2364   */
2365  public static <K, V> BiMap<K, V> filterValues(
2366      BiMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2367    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2368  }
2369
2370  /**
2371   * Returns a map containing the mappings in {@code unfiltered} that satisfy a predicate. The
2372   * returned map is a live view of {@code unfiltered}; changes to one affect the other.
2373   *
2374   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2375   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2376   * and its views. When given a key/value pair that doesn't satisfy the predicate, the map's {@code
2377   * put()} and {@code putAll()} methods throw an {@link IllegalArgumentException}. Similarly, the
2378   * map's entries have a {@link Entry#setValue} method that throws an {@link
2379   * IllegalArgumentException} when the existing key and the provided value don't satisfy the
2380   * predicate.
2381   *
2382   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2383   * or its views, only mappings that satisfy the filter will be removed from the underlying map.
2384   *
2385   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2386   *
2387   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2388   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2389   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2390   *
2391   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals</i>, as documented
2392   * at {@link Predicate#apply}.
2393   */
2394  public static <K, V> Map<K, V> filterEntries(
2395      Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2396    checkNotNull(entryPredicate);
2397    return (unfiltered instanceof AbstractFilteredMap)
2398        ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate)
2399        : new FilteredEntryMap<K, V>(checkNotNull(unfiltered), entryPredicate);
2400  }
2401
2402  /**
2403   * Returns a sorted map containing the mappings in {@code unfiltered} that satisfy a predicate.
2404   * The returned map is a live view of {@code unfiltered}; changes to one affect the other.
2405   *
2406   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2407   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2408   * and its views. When given a key/value pair that doesn't satisfy the predicate, the map's {@code
2409   * put()} and {@code putAll()} methods throw an {@link IllegalArgumentException}. Similarly, the
2410   * map's entries have a {@link Entry#setValue} method that throws an {@link
2411   * IllegalArgumentException} when the existing key and the provided value don't satisfy the
2412   * predicate.
2413   *
2414   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2415   * or its views, only mappings that satisfy the filter will be removed from the underlying map.
2416   *
2417   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2418   *
2419   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2420   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2421   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2422   *
2423   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals</i>, as documented
2424   * at {@link Predicate#apply}.
2425   *
2426   * @since 11.0
2427   */
2428  public static <K, V> SortedMap<K, V> filterEntries(
2429      SortedMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2430    checkNotNull(entryPredicate);
2431    return (unfiltered instanceof FilteredEntrySortedMap)
2432        ? filterFiltered((FilteredEntrySortedMap<K, V>) unfiltered, entryPredicate)
2433        : new FilteredEntrySortedMap<K, V>(checkNotNull(unfiltered), entryPredicate);
2434  }
2435
2436  /**
2437   * Returns a sorted map containing the mappings in {@code unfiltered} that satisfy a predicate.
2438   * The returned map is a live view of {@code unfiltered}; changes to one affect the other.
2439   *
2440   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2441   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2442   * and its views. When given a key/value pair that doesn't satisfy the predicate, the map's {@code
2443   * put()} and {@code putAll()} methods throw an {@link IllegalArgumentException}. Similarly, the
2444   * map's entries have a {@link Entry#setValue} method that throws an {@link
2445   * IllegalArgumentException} when the existing key and the provided value don't satisfy the
2446   * predicate.
2447   *
2448   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2449   * or its views, only mappings that satisfy the filter will be removed from the underlying map.
2450   *
2451   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2452   *
2453   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2454   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2455   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2456   *
2457   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals</i>, as documented
2458   * at {@link Predicate#apply}.
2459   *
2460   * @since 14.0
2461   */
2462  @GwtIncompatible // NavigableMap
2463  public static <K, V> NavigableMap<K, V> filterEntries(
2464      NavigableMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2465    checkNotNull(entryPredicate);
2466    return (unfiltered instanceof FilteredEntryNavigableMap)
2467        ? filterFiltered((FilteredEntryNavigableMap<K, V>) unfiltered, entryPredicate)
2468        : new FilteredEntryNavigableMap<K, V>(checkNotNull(unfiltered), entryPredicate);
2469  }
2470
2471  /**
2472   * Returns a bimap containing the mappings in {@code unfiltered} that satisfy a predicate. The
2473   * returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
2474   *
2475   * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2476   * iterators that don't support {@code remove()}, but all other methods are supported by the bimap
2477   * and its views. When given a key/value pair that doesn't satisfy the predicate, the bimap's
2478   * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link
2479   * IllegalArgumentException}. Similarly, the map's entries have an {@link Entry#setValue} method
2480   * that throws an {@link IllegalArgumentException} when the existing key and the provided value
2481   * don't satisfy the predicate.
2482   *
2483   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2484   * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
2485   * bimap.
2486   *
2487   * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2488   *
2489   * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every key/value
2490   * mapping in the underlying bimap and determine which satisfy the filter. When a live view is
2491   * <i>not</i> needed, it may be faster to copy the filtered bimap and use the copy.
2492   *
2493   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as documented
2494   * at {@link Predicate#apply}.
2495   *
2496   * @since 14.0
2497   */
2498  public static <K, V> BiMap<K, V> filterEntries(
2499      BiMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2500    checkNotNull(unfiltered);
2501    checkNotNull(entryPredicate);
2502    return (unfiltered instanceof FilteredEntryBiMap)
2503        ? filterFiltered((FilteredEntryBiMap<K, V>) unfiltered, entryPredicate)
2504        : new FilteredEntryBiMap<K, V>(unfiltered, entryPredicate);
2505  }
2506
2507  /**
2508   * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when filtering a filtered
2509   * map.
2510   */
2511  private static <K, V> Map<K, V> filterFiltered(
2512      AbstractFilteredMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
2513    return new FilteredEntryMap<>(
2514        map.unfiltered, Predicates.<Entry<K, V>>and(map.predicate, entryPredicate));
2515  }
2516
2517  /**
2518   * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when filtering a filtered
2519   * sorted map.
2520   */
2521  private static <K, V> SortedMap<K, V> filterFiltered(
2522      FilteredEntrySortedMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
2523    Predicate<Entry<K, V>> predicate = Predicates.<Entry<K, V>>and(map.predicate, entryPredicate);
2524    return new FilteredEntrySortedMap<>(map.sortedMap(), predicate);
2525  }
2526
2527  /**
2528   * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when filtering a filtered
2529   * navigable map.
2530   */
2531  @GwtIncompatible // NavigableMap
2532  private static <K, V> NavigableMap<K, V> filterFiltered(
2533      FilteredEntryNavigableMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
2534    Predicate<Entry<K, V>> predicate =
2535        Predicates.<Entry<K, V>>and(map.entryPredicate, entryPredicate);
2536    return new FilteredEntryNavigableMap<>(map.unfiltered, predicate);
2537  }
2538
2539  /**
2540   * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when filtering a filtered
2541   * map.
2542   */
2543  private static <K, V> BiMap<K, V> filterFiltered(
2544      FilteredEntryBiMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
2545    Predicate<Entry<K, V>> predicate = Predicates.<Entry<K, V>>and(map.predicate, entryPredicate);
2546    return new FilteredEntryBiMap<>(map.unfiltered(), predicate);
2547  }
2548
2549  private abstract static class AbstractFilteredMap<K, V> extends ViewCachingAbstractMap<K, V> {
2550    final Map<K, V> unfiltered;
2551    final Predicate<? super Entry<K, V>> predicate;
2552
2553    AbstractFilteredMap(Map<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
2554      this.unfiltered = unfiltered;
2555      this.predicate = predicate;
2556    }
2557
2558    boolean apply(@NullableDecl Object key, @NullableDecl V value) {
2559      // This method is called only when the key is in the map, implying that
2560      // key is a K.
2561      @SuppressWarnings("unchecked")
2562      K k = (K) key;
2563      return predicate.apply(Maps.immutableEntry(k, value));
2564    }
2565
2566    @Override
2567    public V put(K key, V value) {
2568      checkArgument(apply(key, value));
2569      return unfiltered.put(key, value);
2570    }
2571
2572    @Override
2573    public void putAll(Map<? extends K, ? extends V> map) {
2574      for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
2575        checkArgument(apply(entry.getKey(), entry.getValue()));
2576      }
2577      unfiltered.putAll(map);
2578    }
2579
2580    @Override
2581    public boolean containsKey(Object key) {
2582      return unfiltered.containsKey(key) && apply(key, unfiltered.get(key));
2583    }
2584
2585    @Override
2586    public V get(Object key) {
2587      V value = unfiltered.get(key);
2588      return ((value != null) && apply(key, value)) ? value : null;
2589    }
2590
2591    @Override
2592    public boolean isEmpty() {
2593      return entrySet().isEmpty();
2594    }
2595
2596    @Override
2597    public V remove(Object key) {
2598      return containsKey(key) ? unfiltered.remove(key) : null;
2599    }
2600
2601    @Override
2602    Collection<V> createValues() {
2603      return new FilteredMapValues<>(this, unfiltered, predicate);
2604    }
2605  }
2606
2607  private static final class FilteredMapValues<K, V> extends Maps.Values<K, V> {
2608    final Map<K, V> unfiltered;
2609    final Predicate<? super Entry<K, V>> predicate;
2610
2611    FilteredMapValues(
2612        Map<K, V> filteredMap, Map<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
2613      super(filteredMap);
2614      this.unfiltered = unfiltered;
2615      this.predicate = predicate;
2616    }
2617
2618    @Override
2619    public boolean remove(Object o) {
2620      Iterator<Entry<K, V>> entryItr = unfiltered.entrySet().iterator();
2621      while (entryItr.hasNext()) {
2622        Entry<K, V> entry = entryItr.next();
2623        if (predicate.apply(entry) && Objects.equal(entry.getValue(), o)) {
2624          entryItr.remove();
2625          return true;
2626        }
2627      }
2628      return false;
2629    }
2630
2631    @Override
2632    public boolean removeAll(Collection<?> collection) {
2633      Iterator<Entry<K, V>> entryItr = unfiltered.entrySet().iterator();
2634      boolean result = false;
2635      while (entryItr.hasNext()) {
2636        Entry<K, V> entry = entryItr.next();
2637        if (predicate.apply(entry) && collection.contains(entry.getValue())) {
2638          entryItr.remove();
2639          result = true;
2640        }
2641      }
2642      return result;
2643    }
2644
2645    @Override
2646    public boolean retainAll(Collection<?> collection) {
2647      Iterator<Entry<K, V>> entryItr = unfiltered.entrySet().iterator();
2648      boolean result = false;
2649      while (entryItr.hasNext()) {
2650        Entry<K, V> entry = entryItr.next();
2651        if (predicate.apply(entry) && !collection.contains(entry.getValue())) {
2652          entryItr.remove();
2653          result = true;
2654        }
2655      }
2656      return result;
2657    }
2658
2659    @Override
2660    public Object[] toArray() {
2661      // creating an ArrayList so filtering happens once
2662      return Lists.newArrayList(iterator()).toArray();
2663    }
2664
2665    @Override
2666    public <T> T[] toArray(T[] array) {
2667      return Lists.newArrayList(iterator()).toArray(array);
2668    }
2669  }
2670
2671  private static class FilteredKeyMap<K, V> extends AbstractFilteredMap<K, V> {
2672    final Predicate<? super K> keyPredicate;
2673
2674    FilteredKeyMap(
2675        Map<K, V> unfiltered,
2676        Predicate<? super K> keyPredicate,
2677        Predicate<? super Entry<K, V>> entryPredicate) {
2678      super(unfiltered, entryPredicate);
2679      this.keyPredicate = keyPredicate;
2680    }
2681
2682    @Override
2683    protected Set<Entry<K, V>> createEntrySet() {
2684      return Sets.filter(unfiltered.entrySet(), predicate);
2685    }
2686
2687    @Override
2688    Set<K> createKeySet() {
2689      return Sets.filter(unfiltered.keySet(), keyPredicate);
2690    }
2691
2692    // The cast is called only when the key is in the unfiltered map, implying
2693    // that key is a K.
2694    @Override
2695    @SuppressWarnings("unchecked")
2696    public boolean containsKey(Object key) {
2697      return unfiltered.containsKey(key) && keyPredicate.apply((K) key);
2698    }
2699  }
2700
2701  static class FilteredEntryMap<K, V> extends AbstractFilteredMap<K, V> {
2702    /**
2703     * Entries in this set satisfy the predicate, but they don't validate the input to {@code
2704     * Entry.setValue()}.
2705     */
2706    final Set<Entry<K, V>> filteredEntrySet;
2707
2708    FilteredEntryMap(Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2709      super(unfiltered, entryPredicate);
2710      filteredEntrySet = Sets.filter(unfiltered.entrySet(), predicate);
2711    }
2712
2713    @Override
2714    protected Set<Entry<K, V>> createEntrySet() {
2715      return new EntrySet();
2716    }
2717
2718    @WeakOuter
2719    private class EntrySet extends ForwardingSet<Entry<K, V>> {
2720      @Override
2721      protected Set<Entry<K, V>> delegate() {
2722        return filteredEntrySet;
2723      }
2724
2725      @Override
2726      public Iterator<Entry<K, V>> iterator() {
2727        return new TransformedIterator<Entry<K, V>, Entry<K, V>>(filteredEntrySet.iterator()) {
2728          @Override
2729          Entry<K, V> transform(final Entry<K, V> entry) {
2730            return new ForwardingMapEntry<K, V>() {
2731              @Override
2732              protected Entry<K, V> delegate() {
2733                return entry;
2734              }
2735
2736              @Override
2737              public V setValue(V newValue) {
2738                checkArgument(apply(getKey(), newValue));
2739                return super.setValue(newValue);
2740              }
2741            };
2742          }
2743        };
2744      }
2745    }
2746
2747    @Override
2748    Set<K> createKeySet() {
2749      return new KeySet();
2750    }
2751
2752    static <K, V> boolean removeAllKeys(
2753        Map<K, V> map, Predicate<? super Entry<K, V>> entryPredicate, Collection<?> keyCollection) {
2754      Iterator<Entry<K, V>> entryItr = map.entrySet().iterator();
2755      boolean result = false;
2756      while (entryItr.hasNext()) {
2757        Entry<K, V> entry = entryItr.next();
2758        if (entryPredicate.apply(entry) && keyCollection.contains(entry.getKey())) {
2759          entryItr.remove();
2760          result = true;
2761        }
2762      }
2763      return result;
2764    }
2765
2766    static <K, V> boolean retainAllKeys(
2767        Map<K, V> map, Predicate<? super Entry<K, V>> entryPredicate, Collection<?> keyCollection) {
2768      Iterator<Entry<K, V>> entryItr = map.entrySet().iterator();
2769      boolean result = false;
2770      while (entryItr.hasNext()) {
2771        Entry<K, V> entry = entryItr.next();
2772        if (entryPredicate.apply(entry) && !keyCollection.contains(entry.getKey())) {
2773          entryItr.remove();
2774          result = true;
2775        }
2776      }
2777      return result;
2778    }
2779
2780    @WeakOuter
2781    class KeySet extends Maps.KeySet<K, V> {
2782      KeySet() {
2783        super(FilteredEntryMap.this);
2784      }
2785
2786      @Override
2787      public boolean remove(Object o) {
2788        if (containsKey(o)) {
2789          unfiltered.remove(o);
2790          return true;
2791        }
2792        return false;
2793      }
2794
2795      @Override
2796      public boolean removeAll(Collection<?> collection) {
2797        return removeAllKeys(unfiltered, predicate, collection);
2798      }
2799
2800      @Override
2801      public boolean retainAll(Collection<?> collection) {
2802        return retainAllKeys(unfiltered, predicate, collection);
2803      }
2804
2805      @Override
2806      public Object[] toArray() {
2807        // creating an ArrayList so filtering happens once
2808        return Lists.newArrayList(iterator()).toArray();
2809      }
2810
2811      @Override
2812      public <T> T[] toArray(T[] array) {
2813        return Lists.newArrayList(iterator()).toArray(array);
2814      }
2815    }
2816  }
2817
2818  private static class FilteredEntrySortedMap<K, V> extends FilteredEntryMap<K, V>
2819      implements SortedMap<K, V> {
2820
2821    FilteredEntrySortedMap(
2822        SortedMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2823      super(unfiltered, entryPredicate);
2824    }
2825
2826    SortedMap<K, V> sortedMap() {
2827      return (SortedMap<K, V>) unfiltered;
2828    }
2829
2830    @Override
2831    public SortedSet<K> keySet() {
2832      return (SortedSet<K>) super.keySet();
2833    }
2834
2835    @Override
2836    SortedSet<K> createKeySet() {
2837      return new SortedKeySet();
2838    }
2839
2840    @WeakOuter
2841    class SortedKeySet extends KeySet implements SortedSet<K> {
2842      @Override
2843      public Comparator<? super K> comparator() {
2844        return sortedMap().comparator();
2845      }
2846
2847      @Override
2848      public SortedSet<K> subSet(K fromElement, K toElement) {
2849        return (SortedSet<K>) subMap(fromElement, toElement).keySet();
2850      }
2851
2852      @Override
2853      public SortedSet<K> headSet(K toElement) {
2854        return (SortedSet<K>) headMap(toElement).keySet();
2855      }
2856
2857      @Override
2858      public SortedSet<K> tailSet(K fromElement) {
2859        return (SortedSet<K>) tailMap(fromElement).keySet();
2860      }
2861
2862      @Override
2863      public K first() {
2864        return firstKey();
2865      }
2866
2867      @Override
2868      public K last() {
2869        return lastKey();
2870      }
2871    }
2872
2873    @Override
2874    public Comparator<? super K> comparator() {
2875      return sortedMap().comparator();
2876    }
2877
2878    @Override
2879    public K firstKey() {
2880      // correctly throws NoSuchElementException when filtered map is empty.
2881      return keySet().iterator().next();
2882    }
2883
2884    @Override
2885    public K lastKey() {
2886      SortedMap<K, V> headMap = sortedMap();
2887      while (true) {
2888        // correctly throws NoSuchElementException when filtered map is empty.
2889        K key = headMap.lastKey();
2890        if (apply(key, unfiltered.get(key))) {
2891          return key;
2892        }
2893        headMap = sortedMap().headMap(key);
2894      }
2895    }
2896
2897    @Override
2898    public SortedMap<K, V> headMap(K toKey) {
2899      return new FilteredEntrySortedMap<>(sortedMap().headMap(toKey), predicate);
2900    }
2901
2902    @Override
2903    public SortedMap<K, V> subMap(K fromKey, K toKey) {
2904      return new FilteredEntrySortedMap<>(sortedMap().subMap(fromKey, toKey), predicate);
2905    }
2906
2907    @Override
2908    public SortedMap<K, V> tailMap(K fromKey) {
2909      return new FilteredEntrySortedMap<>(sortedMap().tailMap(fromKey), predicate);
2910    }
2911  }
2912
2913  @GwtIncompatible // NavigableMap
2914  private static class FilteredEntryNavigableMap<K, V> extends AbstractNavigableMap<K, V> {
2915    /*
2916     * It's less code to extend AbstractNavigableMap and forward the filtering logic to
2917     * FilteredEntryMap than to extend FilteredEntrySortedMap and reimplement all the NavigableMap
2918     * methods.
2919     */
2920
2921    private final NavigableMap<K, V> unfiltered;
2922    private final Predicate<? super Entry<K, V>> entryPredicate;
2923    private final Map<K, V> filteredDelegate;
2924
2925    FilteredEntryNavigableMap(
2926        NavigableMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2927      this.unfiltered = checkNotNull(unfiltered);
2928      this.entryPredicate = entryPredicate;
2929      this.filteredDelegate = new FilteredEntryMap<>(unfiltered, entryPredicate);
2930    }
2931
2932    @Override
2933    public Comparator<? super K> comparator() {
2934      return unfiltered.comparator();
2935    }
2936
2937    @Override
2938    public NavigableSet<K> navigableKeySet() {
2939      return new Maps.NavigableKeySet<K, V>(this) {
2940        @Override
2941        public boolean removeAll(Collection<?> collection) {
2942          return FilteredEntryMap.removeAllKeys(unfiltered, entryPredicate, collection);
2943        }
2944
2945        @Override
2946        public boolean retainAll(Collection<?> collection) {
2947          return FilteredEntryMap.retainAllKeys(unfiltered, entryPredicate, collection);
2948        }
2949      };
2950    }
2951
2952    @Override
2953    public Collection<V> values() {
2954      return new FilteredMapValues<>(this, unfiltered, entryPredicate);
2955    }
2956
2957    @Override
2958    Iterator<Entry<K, V>> entryIterator() {
2959      return Iterators.filter(unfiltered.entrySet().iterator(), entryPredicate);
2960    }
2961
2962    @Override
2963    Iterator<Entry<K, V>> descendingEntryIterator() {
2964      return Iterators.filter(unfiltered.descendingMap().entrySet().iterator(), entryPredicate);
2965    }
2966
2967    @Override
2968    public int size() {
2969      return filteredDelegate.size();
2970    }
2971
2972    @Override
2973    public boolean isEmpty() {
2974      return !Iterables.any(unfiltered.entrySet(), entryPredicate);
2975    }
2976
2977    @Override
2978    @NullableDecl
2979    public V get(@NullableDecl Object key) {
2980      return filteredDelegate.get(key);
2981    }
2982
2983    @Override
2984    public boolean containsKey(@NullableDecl Object key) {
2985      return filteredDelegate.containsKey(key);
2986    }
2987
2988    @Override
2989    public V put(K key, V value) {
2990      return filteredDelegate.put(key, value);
2991    }
2992
2993    @Override
2994    public V remove(@NullableDecl Object key) {
2995      return filteredDelegate.remove(key);
2996    }
2997
2998    @Override
2999    public void putAll(Map<? extends K, ? extends V> m) {
3000      filteredDelegate.putAll(m);
3001    }
3002
3003    @Override
3004    public void clear() {
3005      filteredDelegate.clear();
3006    }
3007
3008    @Override
3009    public Set<Entry<K, V>> entrySet() {
3010      return filteredDelegate.entrySet();
3011    }
3012
3013    @Override
3014    public Entry<K, V> pollFirstEntry() {
3015      return Iterables.removeFirstMatching(unfiltered.entrySet(), entryPredicate);
3016    }
3017
3018    @Override
3019    public Entry<K, V> pollLastEntry() {
3020      return Iterables.removeFirstMatching(unfiltered.descendingMap().entrySet(), entryPredicate);
3021    }
3022
3023    @Override
3024    public NavigableMap<K, V> descendingMap() {
3025      return filterEntries(unfiltered.descendingMap(), entryPredicate);
3026    }
3027
3028    @Override
3029    public NavigableMap<K, V> subMap(
3030        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
3031      return filterEntries(
3032          unfiltered.subMap(fromKey, fromInclusive, toKey, toInclusive), entryPredicate);
3033    }
3034
3035    @Override
3036    public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
3037      return filterEntries(unfiltered.headMap(toKey, inclusive), entryPredicate);
3038    }
3039
3040    @Override
3041    public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
3042      return filterEntries(unfiltered.tailMap(fromKey, inclusive), entryPredicate);
3043    }
3044  }
3045
3046  static final class FilteredEntryBiMap<K, V> extends FilteredEntryMap<K, V>
3047      implements BiMap<K, V> {
3048    @RetainedWith private final BiMap<V, K> inverse;
3049
3050    private static <K, V> Predicate<Entry<V, K>> inversePredicate(
3051        final Predicate<? super Entry<K, V>> forwardPredicate) {
3052      return new Predicate<Entry<V, K>>() {
3053        @Override
3054        public boolean apply(Entry<V, K> input) {
3055          return forwardPredicate.apply(Maps.immutableEntry(input.getValue(), input.getKey()));
3056        }
3057      };
3058    }
3059
3060    FilteredEntryBiMap(BiMap<K, V> delegate, Predicate<? super Entry<K, V>> predicate) {
3061      super(delegate, predicate);
3062      this.inverse =
3063          new FilteredEntryBiMap<>(delegate.inverse(), inversePredicate(predicate), this);
3064    }
3065
3066    private FilteredEntryBiMap(
3067        BiMap<K, V> delegate, Predicate<? super Entry<K, V>> predicate, BiMap<V, K> inverse) {
3068      super(delegate, predicate);
3069      this.inverse = inverse;
3070    }
3071
3072    BiMap<K, V> unfiltered() {
3073      return (BiMap<K, V>) unfiltered;
3074    }
3075
3076    @Override
3077    public V forcePut(@NullableDecl K key, @NullableDecl V value) {
3078      checkArgument(apply(key, value));
3079      return unfiltered().forcePut(key, value);
3080    }
3081
3082    @Override
3083    public BiMap<V, K> inverse() {
3084      return inverse;
3085    }
3086
3087    @Override
3088    public Set<V> values() {
3089      return inverse.keySet();
3090    }
3091  }
3092
3093  /**
3094   * Returns an unmodifiable view of the specified navigable map. Query operations on the returned
3095   * map read through to the specified map, and attempts to modify the returned map, whether direct
3096   * or via its views, result in an {@code UnsupportedOperationException}.
3097   *
3098   * <p>The returned navigable map will be serializable if the specified navigable map is
3099   * serializable.
3100   *
3101   * <p>This method's signature will not permit you to convert a {@code NavigableMap<? extends K,
3102   * V>} to a {@code NavigableMap<K, V>}. If it permitted this, the returned map's {@code
3103   * comparator()} method might return a {@code Comparator<? extends K>}, which works only on a
3104   * particular subtype of {@code K}, but promise that it's a {@code Comparator<? super K>}, which
3105   * must work on any type of {@code K}.
3106   *
3107   * @param map the navigable map for which an unmodifiable view is to be returned
3108   * @return an unmodifiable view of the specified navigable map
3109   * @since 12.0
3110   */
3111  @GwtIncompatible // NavigableMap
3112  public static <K, V> NavigableMap<K, V> unmodifiableNavigableMap(
3113      NavigableMap<K, ? extends V> map) {
3114    checkNotNull(map);
3115    if (map instanceof UnmodifiableNavigableMap) {
3116      @SuppressWarnings("unchecked") // covariant
3117      NavigableMap<K, V> result = (NavigableMap<K, V>) map;
3118      return result;
3119    } else {
3120      return new UnmodifiableNavigableMap<>(map);
3121    }
3122  }
3123
3124  @NullableDecl
3125  private static <K, V> Entry<K, V> unmodifiableOrNull(@NullableDecl Entry<K, ? extends V> entry) {
3126    return (entry == null) ? null : Maps.unmodifiableEntry(entry);
3127  }
3128
3129  @GwtIncompatible // NavigableMap
3130  static class UnmodifiableNavigableMap<K, V> extends ForwardingSortedMap<K, V>
3131      implements NavigableMap<K, V>, Serializable {
3132    private final NavigableMap<K, ? extends V> delegate;
3133
3134    UnmodifiableNavigableMap(NavigableMap<K, ? extends V> delegate) {
3135      this.delegate = delegate;
3136    }
3137
3138    UnmodifiableNavigableMap(
3139        NavigableMap<K, ? extends V> delegate, UnmodifiableNavigableMap<K, V> descendingMap) {
3140      this.delegate = delegate;
3141      this.descendingMap = descendingMap;
3142    }
3143
3144    @Override
3145    protected SortedMap<K, V> delegate() {
3146      return Collections.unmodifiableSortedMap(delegate);
3147    }
3148
3149    @Override
3150    public Entry<K, V> lowerEntry(K key) {
3151      return unmodifiableOrNull(delegate.lowerEntry(key));
3152    }
3153
3154    @Override
3155    public K lowerKey(K key) {
3156      return delegate.lowerKey(key);
3157    }
3158
3159    @Override
3160    public Entry<K, V> floorEntry(K key) {
3161      return unmodifiableOrNull(delegate.floorEntry(key));
3162    }
3163
3164    @Override
3165    public K floorKey(K key) {
3166      return delegate.floorKey(key);
3167    }
3168
3169    @Override
3170    public Entry<K, V> ceilingEntry(K key) {
3171      return unmodifiableOrNull(delegate.ceilingEntry(key));
3172    }
3173
3174    @Override
3175    public K ceilingKey(K key) {
3176      return delegate.ceilingKey(key);
3177    }
3178
3179    @Override
3180    public Entry<K, V> higherEntry(K key) {
3181      return unmodifiableOrNull(delegate.higherEntry(key));
3182    }
3183
3184    @Override
3185    public K higherKey(K key) {
3186      return delegate.higherKey(key);
3187    }
3188
3189    @Override
3190    public Entry<K, V> firstEntry() {
3191      return unmodifiableOrNull(delegate.firstEntry());
3192    }
3193
3194    @Override
3195    public Entry<K, V> lastEntry() {
3196      return unmodifiableOrNull(delegate.lastEntry());
3197    }
3198
3199    @Override
3200    public final Entry<K, V> pollFirstEntry() {
3201      throw new UnsupportedOperationException();
3202    }
3203
3204    @Override
3205    public final Entry<K, V> pollLastEntry() {
3206      throw new UnsupportedOperationException();
3207    }
3208
3209    @NullableDecl private transient UnmodifiableNavigableMap<K, V> descendingMap;
3210
3211    @Override
3212    public NavigableMap<K, V> descendingMap() {
3213      UnmodifiableNavigableMap<K, V> result = descendingMap;
3214      return (result == null)
3215          ? descendingMap = new UnmodifiableNavigableMap<>(delegate.descendingMap(), this)
3216          : result;
3217    }
3218
3219    @Override
3220    public Set<K> keySet() {
3221      return navigableKeySet();
3222    }
3223
3224    @Override
3225    public NavigableSet<K> navigableKeySet() {
3226      return Sets.unmodifiableNavigableSet(delegate.navigableKeySet());
3227    }
3228
3229    @Override
3230    public NavigableSet<K> descendingKeySet() {
3231      return Sets.unmodifiableNavigableSet(delegate.descendingKeySet());
3232    }
3233
3234    @Override
3235    public SortedMap<K, V> subMap(K fromKey, K toKey) {
3236      return subMap(fromKey, true, toKey, false);
3237    }
3238
3239    @Override
3240    public NavigableMap<K, V> subMap(
3241        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
3242      return Maps.unmodifiableNavigableMap(
3243          delegate.subMap(fromKey, fromInclusive, toKey, toInclusive));
3244    }
3245
3246    @Override
3247    public SortedMap<K, V> headMap(K toKey) {
3248      return headMap(toKey, false);
3249    }
3250
3251    @Override
3252    public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
3253      return Maps.unmodifiableNavigableMap(delegate.headMap(toKey, inclusive));
3254    }
3255
3256    @Override
3257    public SortedMap<K, V> tailMap(K fromKey) {
3258      return tailMap(fromKey, true);
3259    }
3260
3261    @Override
3262    public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
3263      return Maps.unmodifiableNavigableMap(delegate.tailMap(fromKey, inclusive));
3264    }
3265  }
3266
3267  /**
3268   * Returns a synchronized (thread-safe) navigable map backed by the specified navigable map. In
3269   * order to guarantee serial access, it is critical that <b>all</b> access to the backing
3270   * navigable map is accomplished through the returned navigable map (or its views).
3271   *
3272   * <p>It is imperative that the user manually synchronize on the returned navigable map when
3273   * iterating over any of its collection views, or the collections views of any of its {@code
3274   * descendingMap}, {@code subMap}, {@code headMap} or {@code tailMap} views.
3275   *
3276   * <pre>{@code
3277   * NavigableMap<K, V> map = synchronizedNavigableMap(new TreeMap<K, V>());
3278   *
3279   * // Needn't be in synchronized block
3280   * NavigableSet<K> set = map.navigableKeySet();
3281   *
3282   * synchronized (map) { // Synchronizing on map, not set!
3283   *   Iterator<K> it = set.iterator(); // Must be in synchronized block
3284   *   while (it.hasNext()) {
3285   *     foo(it.next());
3286   *   }
3287   * }
3288   * }</pre>
3289   *
3290   * <p>or:
3291   *
3292   * <pre>{@code
3293   * NavigableMap<K, V> map = synchronizedNavigableMap(new TreeMap<K, V>());
3294   * NavigableMap<K, V> map2 = map.subMap(foo, false, bar, true);
3295   *
3296   * // Needn't be in synchronized block
3297   * NavigableSet<K> set2 = map2.descendingKeySet();
3298   *
3299   * synchronized (map) { // Synchronizing on map, not map2 or set2!
3300   *   Iterator<K> it = set2.iterator(); // Must be in synchronized block
3301   *   while (it.hasNext()) {
3302   *     foo(it.next());
3303   *   }
3304   * }
3305   * }</pre>
3306   *
3307   * <p>Failure to follow this advice may result in non-deterministic behavior.
3308   *
3309   * <p>The returned navigable map will be serializable if the specified navigable map is
3310   * serializable.
3311   *
3312   * @param navigableMap the navigable map to be "wrapped" in a synchronized navigable map.
3313   * @return a synchronized view of the specified navigable map.
3314   * @since 13.0
3315   */
3316  @GwtIncompatible // NavigableMap
3317  public static <K, V> NavigableMap<K, V> synchronizedNavigableMap(
3318      NavigableMap<K, V> navigableMap) {
3319    return Synchronized.navigableMap(navigableMap);
3320  }
3321
3322  /**
3323   * {@code AbstractMap} extension that makes it easy to cache customized keySet, values, and
3324   * entrySet views.
3325   */
3326  @GwtCompatible
3327  abstract static class ViewCachingAbstractMap<K, V> extends AbstractMap<K, V> {
3328    /**
3329     * Creates the entry set to be returned by {@link #entrySet()}. This method is invoked at most
3330     * once on a given map, at the time when {@code entrySet} is first called.
3331     */
3332    abstract Set<Entry<K, V>> createEntrySet();
3333
3334    @NullableDecl private transient Set<Entry<K, V>> entrySet;
3335
3336    @Override
3337    public Set<Entry<K, V>> entrySet() {
3338      Set<Entry<K, V>> result = entrySet;
3339      return (result == null) ? entrySet = createEntrySet() : result;
3340    }
3341
3342    @NullableDecl private transient Set<K> keySet;
3343
3344    @Override
3345    public Set<K> keySet() {
3346      Set<K> result = keySet;
3347      return (result == null) ? keySet = createKeySet() : result;
3348    }
3349
3350    Set<K> createKeySet() {
3351      return new KeySet<>(this);
3352    }
3353
3354    @NullableDecl private transient Collection<V> values;
3355
3356    @Override
3357    public Collection<V> values() {
3358      Collection<V> result = values;
3359      return (result == null) ? values = createValues() : result;
3360    }
3361
3362    Collection<V> createValues() {
3363      return new Values<>(this);
3364    }
3365  }
3366
3367  abstract static class IteratorBasedAbstractMap<K, V> extends AbstractMap<K, V> {
3368    @Override
3369    public abstract int size();
3370
3371    abstract Iterator<Entry<K, V>> entryIterator();
3372
3373    @Override
3374    public Set<Entry<K, V>> entrySet() {
3375      return new EntrySet<K, V>() {
3376        @Override
3377        Map<K, V> map() {
3378          return IteratorBasedAbstractMap.this;
3379        }
3380
3381        @Override
3382        public Iterator<Entry<K, V>> iterator() {
3383          return entryIterator();
3384        }
3385      };
3386    }
3387
3388    @Override
3389    public void clear() {
3390      Iterators.clear(entryIterator());
3391    }
3392  }
3393
3394  /**
3395   * Delegates to {@link Map#get}. Returns {@code null} on {@code ClassCastException} and {@code
3396   * NullPointerException}.
3397   */
3398  static <V> V safeGet(Map<?, V> map, @NullableDecl Object key) {
3399    checkNotNull(map);
3400    try {
3401      return map.get(key);
3402    } catch (ClassCastException | NullPointerException e) {
3403      return null;
3404    }
3405  }
3406
3407  /**
3408   * Delegates to {@link Map#containsKey}. Returns {@code false} on {@code ClassCastException} and
3409   * {@code NullPointerException}.
3410   */
3411  static boolean safeContainsKey(Map<?, ?> map, Object key) {
3412    checkNotNull(map);
3413    try {
3414      return map.containsKey(key);
3415    } catch (ClassCastException | NullPointerException e) {
3416      return false;
3417    }
3418  }
3419
3420  /**
3421   * Delegates to {@link Map#remove}. Returns {@code null} on {@code ClassCastException} and {@code
3422   * NullPointerException}.
3423   */
3424  static <V> V safeRemove(Map<?, V> map, Object key) {
3425    checkNotNull(map);
3426    try {
3427      return map.remove(key);
3428    } catch (ClassCastException | NullPointerException e) {
3429      return null;
3430    }
3431  }
3432
3433  /** An admittedly inefficient implementation of {@link Map#containsKey}. */
3434  static boolean containsKeyImpl(Map<?, ?> map, @NullableDecl Object key) {
3435    return Iterators.contains(keyIterator(map.entrySet().iterator()), key);
3436  }
3437
3438  /** An implementation of {@link Map#containsValue}. */
3439  static boolean containsValueImpl(Map<?, ?> map, @NullableDecl Object value) {
3440    return Iterators.contains(valueIterator(map.entrySet().iterator()), value);
3441  }
3442
3443  /**
3444   * Implements {@code Collection.contains} safely for forwarding collections of map entries. If
3445   * {@code o} is an instance of {@code Entry}, it is wrapped using {@link #unmodifiableEntry} to
3446   * protect against a possible nefarious equals method.
3447   *
3448   * <p>Note that {@code c} is the backing (delegate) collection, rather than the forwarding
3449   * collection.
3450   *
3451   * @param c the delegate (unwrapped) collection of map entries
3452   * @param o the object that might be contained in {@code c}
3453   * @return {@code true} if {@code c} contains {@code o}
3454   */
3455  static <K, V> boolean containsEntryImpl(Collection<Entry<K, V>> c, Object o) {
3456    if (!(o instanceof Entry)) {
3457      return false;
3458    }
3459    return c.contains(unmodifiableEntry((Entry<?, ?>) o));
3460  }
3461
3462  /**
3463   * Implements {@code Collection.remove} safely for forwarding collections of map entries. If
3464   * {@code o} is an instance of {@code Entry}, it is wrapped using {@link #unmodifiableEntry} to
3465   * protect against a possible nefarious equals method.
3466   *
3467   * <p>Note that {@code c} is backing (delegate) collection, rather than the forwarding collection.
3468   *
3469   * @param c the delegate (unwrapped) collection of map entries
3470   * @param o the object to remove from {@code c}
3471   * @return {@code true} if {@code c} was changed
3472   */
3473  static <K, V> boolean removeEntryImpl(Collection<Entry<K, V>> c, Object o) {
3474    if (!(o instanceof Entry)) {
3475      return false;
3476    }
3477    return c.remove(unmodifiableEntry((Entry<?, ?>) o));
3478  }
3479
3480  /** An implementation of {@link Map#equals}. */
3481  static boolean equalsImpl(Map<?, ?> map, Object object) {
3482    if (map == object) {
3483      return true;
3484    } else if (object instanceof Map) {
3485      Map<?, ?> o = (Map<?, ?>) object;
3486      return map.entrySet().equals(o.entrySet());
3487    }
3488    return false;
3489  }
3490
3491  /** An implementation of {@link Map#toString}. */
3492  static String toStringImpl(Map<?, ?> map) {
3493    StringBuilder sb = Collections2.newStringBuilderForCollection(map.size()).append('{');
3494    boolean first = true;
3495    for (Entry<?, ?> entry : map.entrySet()) {
3496      if (!first) {
3497        sb.append(", ");
3498      }
3499      first = false;
3500      sb.append(entry.getKey()).append('=').append(entry.getValue());
3501    }
3502    return sb.append('}').toString();
3503  }
3504
3505  /** An implementation of {@link Map#putAll}. */
3506  static <K, V> void putAllImpl(Map<K, V> self, Map<? extends K, ? extends V> map) {
3507    for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
3508      self.put(entry.getKey(), entry.getValue());
3509    }
3510  }
3511
3512  static class KeySet<K, V> extends Sets.ImprovedAbstractSet<K> {
3513    @Weak final Map<K, V> map;
3514
3515    KeySet(Map<K, V> map) {
3516      this.map = checkNotNull(map);
3517    }
3518
3519    Map<K, V> map() {
3520      return map;
3521    }
3522
3523    @Override
3524    public Iterator<K> iterator() {
3525      return keyIterator(map().entrySet().iterator());
3526    }
3527
3528    @Override
3529    public int size() {
3530      return map().size();
3531    }
3532
3533    @Override
3534    public boolean isEmpty() {
3535      return map().isEmpty();
3536    }
3537
3538    @Override
3539    public boolean contains(Object o) {
3540      return map().containsKey(o);
3541    }
3542
3543    @Override
3544    public boolean remove(Object o) {
3545      if (contains(o)) {
3546        map().remove(o);
3547        return true;
3548      }
3549      return false;
3550    }
3551
3552    @Override
3553    public void clear() {
3554      map().clear();
3555    }
3556  }
3557
3558  @NullableDecl
3559  static <K> K keyOrNull(@NullableDecl Entry<K, ?> entry) {
3560    return (entry == null) ? null : entry.getKey();
3561  }
3562
3563  @NullableDecl
3564  static <V> V valueOrNull(@NullableDecl Entry<?, V> entry) {
3565    return (entry == null) ? null : entry.getValue();
3566  }
3567
3568  static class SortedKeySet<K, V> extends KeySet<K, V> implements SortedSet<K> {
3569    SortedKeySet(SortedMap<K, V> map) {
3570      super(map);
3571    }
3572
3573    @Override
3574    SortedMap<K, V> map() {
3575      return (SortedMap<K, V>) super.map();
3576    }
3577
3578    @Override
3579    public Comparator<? super K> comparator() {
3580      return map().comparator();
3581    }
3582
3583    @Override
3584    public SortedSet<K> subSet(K fromElement, K toElement) {
3585      return new SortedKeySet<>(map().subMap(fromElement, toElement));
3586    }
3587
3588    @Override
3589    public SortedSet<K> headSet(K toElement) {
3590      return new SortedKeySet<>(map().headMap(toElement));
3591    }
3592
3593    @Override
3594    public SortedSet<K> tailSet(K fromElement) {
3595      return new SortedKeySet<>(map().tailMap(fromElement));
3596    }
3597
3598    @Override
3599    public K first() {
3600      return map().firstKey();
3601    }
3602
3603    @Override
3604    public K last() {
3605      return map().lastKey();
3606    }
3607  }
3608
3609  @GwtIncompatible // NavigableMap
3610  static class NavigableKeySet<K, V> extends SortedKeySet<K, V> implements NavigableSet<K> {
3611    NavigableKeySet(NavigableMap<K, V> map) {
3612      super(map);
3613    }
3614
3615    @Override
3616    NavigableMap<K, V> map() {
3617      return (NavigableMap<K, V>) map;
3618    }
3619
3620    @Override
3621    public K lower(K e) {
3622      return map().lowerKey(e);
3623    }
3624
3625    @Override
3626    public K floor(K e) {
3627      return map().floorKey(e);
3628    }
3629
3630    @Override
3631    public K ceiling(K e) {
3632      return map().ceilingKey(e);
3633    }
3634
3635    @Override
3636    public K higher(K e) {
3637      return map().higherKey(e);
3638    }
3639
3640    @Override
3641    public K pollFirst() {
3642      return keyOrNull(map().pollFirstEntry());
3643    }
3644
3645    @Override
3646    public K pollLast() {
3647      return keyOrNull(map().pollLastEntry());
3648    }
3649
3650    @Override
3651    public NavigableSet<K> descendingSet() {
3652      return map().descendingKeySet();
3653    }
3654
3655    @Override
3656    public Iterator<K> descendingIterator() {
3657      return descendingSet().iterator();
3658    }
3659
3660    @Override
3661    public NavigableSet<K> subSet(
3662        K fromElement, boolean fromInclusive, K toElement, boolean toInclusive) {
3663      return map().subMap(fromElement, fromInclusive, toElement, toInclusive).navigableKeySet();
3664    }
3665
3666    @Override
3667    public SortedSet<K> subSet(K fromElement, K toElement) {
3668      return subSet(fromElement, true, toElement, false);
3669    }
3670
3671    @Override
3672    public NavigableSet<K> headSet(K toElement, boolean inclusive) {
3673      return map().headMap(toElement, inclusive).navigableKeySet();
3674    }
3675
3676    @Override
3677    public SortedSet<K> headSet(K toElement) {
3678      return headSet(toElement, false);
3679    }
3680
3681    @Override
3682    public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
3683      return map().tailMap(fromElement, inclusive).navigableKeySet();
3684    }
3685
3686    @Override
3687    public SortedSet<K> tailSet(K fromElement) {
3688      return tailSet(fromElement, true);
3689    }
3690  }
3691
3692  static class Values<K, V> extends AbstractCollection<V> {
3693    @Weak final Map<K, V> map;
3694
3695    Values(Map<K, V> map) {
3696      this.map = checkNotNull(map);
3697    }
3698
3699    final Map<K, V> map() {
3700      return map;
3701    }
3702
3703    @Override
3704    public Iterator<V> iterator() {
3705      return valueIterator(map().entrySet().iterator());
3706    }
3707
3708    @Override
3709    public boolean remove(Object o) {
3710      try {
3711        return super.remove(o);
3712      } catch (UnsupportedOperationException e) {
3713        for (Entry<K, V> entry : map().entrySet()) {
3714          if (Objects.equal(o, entry.getValue())) {
3715            map().remove(entry.getKey());
3716            return true;
3717          }
3718        }
3719        return false;
3720      }
3721    }
3722
3723    @Override
3724    public boolean removeAll(Collection<?> c) {
3725      try {
3726        return super.removeAll(checkNotNull(c));
3727      } catch (UnsupportedOperationException e) {
3728        Set<K> toRemove = Sets.newHashSet();
3729        for (Entry<K, V> entry : map().entrySet()) {
3730          if (c.contains(entry.getValue())) {
3731            toRemove.add(entry.getKey());
3732          }
3733        }
3734        return map().keySet().removeAll(toRemove);
3735      }
3736    }
3737
3738    @Override
3739    public boolean retainAll(Collection<?> c) {
3740      try {
3741        return super.retainAll(checkNotNull(c));
3742      } catch (UnsupportedOperationException e) {
3743        Set<K> toRetain = Sets.newHashSet();
3744        for (Entry<K, V> entry : map().entrySet()) {
3745          if (c.contains(entry.getValue())) {
3746            toRetain.add(entry.getKey());
3747          }
3748        }
3749        return map().keySet().retainAll(toRetain);
3750      }
3751    }
3752
3753    @Override
3754    public int size() {
3755      return map().size();
3756    }
3757
3758    @Override
3759    public boolean isEmpty() {
3760      return map().isEmpty();
3761    }
3762
3763    @Override
3764    public boolean contains(@NullableDecl Object o) {
3765      return map().containsValue(o);
3766    }
3767
3768    @Override
3769    public void clear() {
3770      map().clear();
3771    }
3772  }
3773
3774  abstract static class EntrySet<K, V> extends Sets.ImprovedAbstractSet<Entry<K, V>> {
3775    abstract Map<K, V> map();
3776
3777    @Override
3778    public int size() {
3779      return map().size();
3780    }
3781
3782    @Override
3783    public void clear() {
3784      map().clear();
3785    }
3786
3787    @Override
3788    public boolean contains(Object o) {
3789      if (o instanceof Entry) {
3790        Entry<?, ?> entry = (Entry<?, ?>) o;
3791        Object key = entry.getKey();
3792        V value = Maps.safeGet(map(), key);
3793        return Objects.equal(value, entry.getValue()) && (value != null || map().containsKey(key));
3794      }
3795      return false;
3796    }
3797
3798    @Override
3799    public boolean isEmpty() {
3800      return map().isEmpty();
3801    }
3802
3803    @Override
3804    public boolean remove(Object o) {
3805      if (contains(o)) {
3806        Entry<?, ?> entry = (Entry<?, ?>) o;
3807        return map().keySet().remove(entry.getKey());
3808      }
3809      return false;
3810    }
3811
3812    @Override
3813    public boolean removeAll(Collection<?> c) {
3814      try {
3815        return super.removeAll(checkNotNull(c));
3816      } catch (UnsupportedOperationException e) {
3817        // if the iterators don't support remove
3818        return Sets.removeAllImpl(this, c.iterator());
3819      }
3820    }
3821
3822    @Override
3823    public boolean retainAll(Collection<?> c) {
3824      try {
3825        return super.retainAll(checkNotNull(c));
3826      } catch (UnsupportedOperationException e) {
3827        // if the iterators don't support remove
3828        Set<Object> keys = Sets.newHashSetWithExpectedSize(c.size());
3829        for (Object o : c) {
3830          if (contains(o)) {
3831            Entry<?, ?> entry = (Entry<?, ?>) o;
3832            keys.add(entry.getKey());
3833          }
3834        }
3835        return map().keySet().retainAll(keys);
3836      }
3837    }
3838  }
3839
3840  @GwtIncompatible // NavigableMap
3841  abstract static class DescendingMap<K, V> extends ForwardingMap<K, V>
3842      implements NavigableMap<K, V> {
3843
3844    abstract NavigableMap<K, V> forward();
3845
3846    @Override
3847    protected final Map<K, V> delegate() {
3848      return forward();
3849    }
3850
3851    @NullableDecl private transient Comparator<? super K> comparator;
3852
3853    @SuppressWarnings("unchecked")
3854    @Override
3855    public Comparator<? super K> comparator() {
3856      Comparator<? super K> result = comparator;
3857      if (result == null) {
3858        Comparator<? super K> forwardCmp = forward().comparator();
3859        if (forwardCmp == null) {
3860          forwardCmp = (Comparator) Ordering.natural();
3861        }
3862        result = comparator = reverse(forwardCmp);
3863      }
3864      return result;
3865    }
3866
3867    // If we inline this, we get a javac error.
3868    private static <T> Ordering<T> reverse(Comparator<T> forward) {
3869      return Ordering.from(forward).reverse();
3870    }
3871
3872    @Override
3873    public K firstKey() {
3874      return forward().lastKey();
3875    }
3876
3877    @Override
3878    public K lastKey() {
3879      return forward().firstKey();
3880    }
3881
3882    @Override
3883    public Entry<K, V> lowerEntry(K key) {
3884      return forward().higherEntry(key);
3885    }
3886
3887    @Override
3888    public K lowerKey(K key) {
3889      return forward().higherKey(key);
3890    }
3891
3892    @Override
3893    public Entry<K, V> floorEntry(K key) {
3894      return forward().ceilingEntry(key);
3895    }
3896
3897    @Override
3898    public K floorKey(K key) {
3899      return forward().ceilingKey(key);
3900    }
3901
3902    @Override
3903    public Entry<K, V> ceilingEntry(K key) {
3904      return forward().floorEntry(key);
3905    }
3906
3907    @Override
3908    public K ceilingKey(K key) {
3909      return forward().floorKey(key);
3910    }
3911
3912    @Override
3913    public Entry<K, V> higherEntry(K key) {
3914      return forward().lowerEntry(key);
3915    }
3916
3917    @Override
3918    public K higherKey(K key) {
3919      return forward().lowerKey(key);
3920    }
3921
3922    @Override
3923    public Entry<K, V> firstEntry() {
3924      return forward().lastEntry();
3925    }
3926
3927    @Override
3928    public Entry<K, V> lastEntry() {
3929      return forward().firstEntry();
3930    }
3931
3932    @Override
3933    public Entry<K, V> pollFirstEntry() {
3934      return forward().pollLastEntry();
3935    }
3936
3937    @Override
3938    public Entry<K, V> pollLastEntry() {
3939      return forward().pollFirstEntry();
3940    }
3941
3942    @Override
3943    public NavigableMap<K, V> descendingMap() {
3944      return forward();
3945    }
3946
3947    @NullableDecl private transient Set<Entry<K, V>> entrySet;
3948
3949    @Override
3950    public Set<Entry<K, V>> entrySet() {
3951      Set<Entry<K, V>> result = entrySet;
3952      return (result == null) ? entrySet = createEntrySet() : result;
3953    }
3954
3955    abstract Iterator<Entry<K, V>> entryIterator();
3956
3957    Set<Entry<K, V>> createEntrySet() {
3958      @WeakOuter
3959      class EntrySetImpl extends EntrySet<K, V> {
3960        @Override
3961        Map<K, V> map() {
3962          return DescendingMap.this;
3963        }
3964
3965        @Override
3966        public Iterator<Entry<K, V>> iterator() {
3967          return entryIterator();
3968        }
3969      }
3970      return new EntrySetImpl();
3971    }
3972
3973    @Override
3974    public Set<K> keySet() {
3975      return navigableKeySet();
3976    }
3977
3978    @NullableDecl private transient NavigableSet<K> navigableKeySet;
3979
3980    @Override
3981    public NavigableSet<K> navigableKeySet() {
3982      NavigableSet<K> result = navigableKeySet;
3983      return (result == null) ? navigableKeySet = new NavigableKeySet<>(this) : result;
3984    }
3985
3986    @Override
3987    public NavigableSet<K> descendingKeySet() {
3988      return forward().navigableKeySet();
3989    }
3990
3991    @Override
3992    public NavigableMap<K, V> subMap(
3993        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
3994      return forward().subMap(toKey, toInclusive, fromKey, fromInclusive).descendingMap();
3995    }
3996
3997    @Override
3998    public SortedMap<K, V> subMap(K fromKey, K toKey) {
3999      return subMap(fromKey, true, toKey, false);
4000    }
4001
4002    @Override
4003    public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
4004      return forward().tailMap(toKey, inclusive).descendingMap();
4005    }
4006
4007    @Override
4008    public SortedMap<K, V> headMap(K toKey) {
4009      return headMap(toKey, false);
4010    }
4011
4012    @Override
4013    public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
4014      return forward().headMap(fromKey, inclusive).descendingMap();
4015    }
4016
4017    @Override
4018    public SortedMap<K, V> tailMap(K fromKey) {
4019      return tailMap(fromKey, true);
4020    }
4021
4022    @Override
4023    public Collection<V> values() {
4024      return new Values<>(this);
4025    }
4026
4027    @Override
4028    public String toString() {
4029      return standardToString();
4030    }
4031  }
4032
4033  /** Returns a map from the ith element of list to i. */
4034  static <E> ImmutableMap<E, Integer> indexMap(Collection<E> list) {
4035    ImmutableMap.Builder<E, Integer> builder = new ImmutableMap.Builder<>(list.size());
4036    int i = 0;
4037    for (E e : list) {
4038      builder.put(e, i++);
4039    }
4040    return builder.build();
4041  }
4042
4043  /**
4044   * Returns a view of the portion of {@code map} whose keys are contained by {@code range}.
4045   *
4046   * <p>This method delegates to the appropriate methods of {@link NavigableMap} (namely {@link
4047   * NavigableMap#subMap(Object, boolean, Object, boolean) subMap()}, {@link
4048   * NavigableMap#tailMap(Object, boolean) tailMap()}, and {@link NavigableMap#headMap(Object,
4049   * boolean) headMap()}) to actually construct the view. Consult these methods for a full
4050   * description of the returned view's behavior.
4051   *
4052   * <p><b>Warning:</b> {@code Range}s always represent a range of values using the values' natural
4053   * ordering. {@code NavigableMap} on the other hand can specify a custom ordering via a {@link
4054   * Comparator}, which can violate the natural ordering. Using this method (or in general using
4055   * {@code Range}) with unnaturally-ordered maps can lead to unexpected and undefined behavior.
4056   *
4057   * @since 20.0
4058   */
4059  @Beta
4060  @GwtIncompatible // NavigableMap
4061  public static <K extends Comparable<? super K>, V> NavigableMap<K, V> subMap(
4062      NavigableMap<K, V> map, Range<K> range) {
4063    if (map.comparator() != null
4064        && map.comparator() != Ordering.natural()
4065        && range.hasLowerBound()
4066        && range.hasUpperBound()) {
4067      checkArgument(
4068          map.comparator().compare(range.lowerEndpoint(), range.upperEndpoint()) <= 0,
4069          "map is using a custom comparator which is inconsistent with the natural ordering.");
4070    }
4071    if (range.hasLowerBound() && range.hasUpperBound()) {
4072      return map.subMap(
4073          range.lowerEndpoint(),
4074          range.lowerBoundType() == BoundType.CLOSED,
4075          range.upperEndpoint(),
4076          range.upperBoundType() == BoundType.CLOSED);
4077    } else if (range.hasLowerBound()) {
4078      return map.tailMap(range.lowerEndpoint(), range.lowerBoundType() == BoundType.CLOSED);
4079    } else if (range.hasUpperBound()) {
4080      return map.headMap(range.upperEndpoint(), range.upperBoundType() == BoundType.CLOSED);
4081    }
4082    return checkNotNull(map);
4083  }
4084}