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