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