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