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