001    /*
002     * Copyright (C) 2007 The Guava Authors
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package com.google.common.collect;
018    
019    import static com.google.common.base.Preconditions.checkArgument;
020    import static com.google.common.base.Preconditions.checkNotNull;
021    
022    import com.google.common.annotations.Beta;
023    import com.google.common.annotations.GwtCompatible;
024    import com.google.common.annotations.GwtIncompatible;
025    import com.google.common.base.Equivalence;
026    import com.google.common.base.Function;
027    import com.google.common.base.Joiner.MapJoiner;
028    import com.google.common.base.Objects;
029    import com.google.common.base.Preconditions;
030    import com.google.common.base.Predicate;
031    import com.google.common.base.Predicates;
032    import com.google.common.collect.MapDifference.ValueDifference;
033    import com.google.common.primitives.Ints;
034    
035    import java.io.Serializable;
036    import java.util.AbstractCollection;
037    import java.util.AbstractMap;
038    import java.util.Collection;
039    import java.util.Collections;
040    import java.util.Comparator;
041    import java.util.EnumMap;
042    import java.util.Enumeration;
043    import java.util.HashMap;
044    import java.util.IdentityHashMap;
045    import java.util.Iterator;
046    import java.util.LinkedHashMap;
047    import java.util.Map;
048    import java.util.Map.Entry;
049    import java.util.Properties;
050    import java.util.Set;
051    import java.util.SortedMap;
052    import java.util.SortedSet;
053    import java.util.TreeMap;
054    import java.util.concurrent.ConcurrentMap;
055    
056    import javax.annotation.Nullable;
057    
058    /**
059     * Static utility methods pertaining to {@link Map} instances (including instances of
060     * {@link SortedMap}, {@link BiMap}, etc.). Also see this class's counterparts
061     * {@link Lists}, {@link Sets} and {@link Queues}.
062     *
063     * <p>See the Guava User Guide article on <a href=
064     * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Maps">
065     * {@code Maps}</a>.
066     *
067     * @author Kevin Bourrillion
068     * @author Mike Bostock
069     * @author Isaac Shum
070     * @author Louis Wasserman
071     * @since 2.0 (imported from Google Collections Library)
072     */
073    @GwtCompatible(emulated = true)
074    public final class Maps {
075      private Maps() {}
076    
077      /**
078       * Creates a <i>mutable</i>, empty {@code HashMap} instance.
079       *
080       * <p><b>Note:</b> if mutability is not required, use {@link
081       * ImmutableMap#of()} instead.
082       *
083       * <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link
084       * #newEnumMap} instead.
085       *
086       * @return a new, empty {@code HashMap}
087       */
088      public static <K, V> HashMap<K, V> newHashMap() {
089        return new HashMap<K, V>();
090      }
091    
092      /**
093       * Creates a {@code HashMap} instance, with a high enough "initial capacity"
094       * that it <i>should</i> hold {@code expectedSize} elements without growth.
095       * This behavior cannot be broadly guaranteed, but it is observed to be true
096       * for OpenJDK 1.6. It also can't be guaranteed that the method isn't
097       * inadvertently <i>oversizing</i> the returned map.
098       *
099       * @param expectedSize the number of elements you expect to add to the
100       *        returned map
101       * @return a new, empty {@code HashMap} with enough capacity to hold {@code
102       *         expectedSize} elements without resizing
103       * @throws IllegalArgumentException if {@code expectedSize} is negative
104       */
105      public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(
106          int expectedSize) {
107        return new HashMap<K, V>(capacity(expectedSize));
108      }
109    
110      /**
111       * Returns a capacity that is sufficient to keep the map from being resized as
112       * long as it grows no larger than expectedSize and the load factor is >= its
113       * default (0.75).
114       */
115      static int capacity(int expectedSize) {
116        if (expectedSize < 3) {
117          checkArgument(expectedSize >= 0);
118          return expectedSize + 1;
119        }
120        if (expectedSize < Ints.MAX_POWER_OF_TWO) {
121          return expectedSize + expectedSize / 3;
122        }
123        return Integer.MAX_VALUE; // any large value
124      }
125    
126      /**
127       * Creates a <i>mutable</i> {@code HashMap} instance with the same mappings as
128       * the specified map.
129       *
130       * <p><b>Note:</b> if mutability is not required, use {@link
131       * ImmutableMap#copyOf(Map)} instead.
132       *
133       * <p><b>Note:</b> if {@code K} is an {@link Enum} type, use {@link
134       * #newEnumMap} instead.
135       *
136       * @param map the mappings to be placed in the new map
137       * @return a new {@code HashMap} initialized with the mappings from {@code
138       *         map}
139       */
140      public static <K, V> HashMap<K, V> newHashMap(
141          Map<? extends K, ? extends V> map) {
142        return new HashMap<K, V>(map);
143      }
144    
145      /**
146       * Creates a <i>mutable</i>, empty, insertion-ordered {@code LinkedHashMap}
147       * instance.
148       *
149       * <p><b>Note:</b> if mutability is not required, use {@link
150       * ImmutableMap#of()} instead.
151       *
152       * @return a new, empty {@code LinkedHashMap}
153       */
154      public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() {
155        return new LinkedHashMap<K, V>();
156      }
157    
158      /**
159       * Creates a <i>mutable</i>, insertion-ordered {@code LinkedHashMap} instance
160       * with the same mappings as the specified map.
161       *
162       * <p><b>Note:</b> if mutability is not required, use {@link
163       * ImmutableMap#copyOf(Map)} instead.
164       *
165       * @param map the mappings to be placed in the new map
166       * @return a new, {@code LinkedHashMap} initialized with the mappings from
167       *         {@code map}
168       */
169      public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(
170          Map<? extends K, ? extends V> map) {
171        return new LinkedHashMap<K, V>(map);
172      }
173    
174      /**
175       * Returns a general-purpose instance of {@code ConcurrentMap}, which supports
176       * all optional operations of the ConcurrentMap interface. It does not permit
177       * null keys or values. It is serializable.
178       *
179       * <p>This is currently accomplished by calling {@link MapMaker#makeMap()}.
180       *
181       * <p>It is preferable to use {@code MapMaker} directly (rather than through
182       * this method), as it presents numerous useful configuration options,
183       * such as the concurrency level, load factor, key/value reference types,
184       * and value computation.
185       *
186       * @return a new, empty {@code ConcurrentMap}
187       * @since 3.0
188       */
189      public static <K, V> ConcurrentMap<K, V> newConcurrentMap() {
190        return new MapMaker().<K, V>makeMap();
191      }
192    
193      /**
194       * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the natural
195       * ordering of its elements.
196       *
197       * <p><b>Note:</b> if mutability is not required, use {@link
198       * ImmutableSortedMap#of()} instead.
199       *
200       * @return a new, empty {@code TreeMap}
201       */
202      public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() {
203        return new TreeMap<K, V>();
204      }
205    
206      /**
207       * Creates a <i>mutable</i> {@code TreeMap} instance with the same mappings as
208       * the specified map and using the same ordering as the specified map.
209       *
210       * <p><b>Note:</b> if mutability is not required, use {@link
211       * ImmutableSortedMap#copyOfSorted(SortedMap)} instead.
212       *
213       * @param map the sorted map whose mappings are to be placed in the new map
214       *        and whose comparator is to be used to sort the new map
215       * @return a new {@code TreeMap} initialized with the mappings from {@code
216       *         map} and using the comparator of {@code map}
217       */
218      public static <K, V> TreeMap<K, V> newTreeMap(SortedMap<K, ? extends V> map) {
219        return new TreeMap<K, V>(map);
220      }
221    
222      /**
223       * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the given
224       * comparator.
225       *
226       * <p><b>Note:</b> if mutability is not required, use {@code
227       * ImmutableSortedMap.orderedBy(comparator).build()} instead.
228       *
229       * @param comparator the comparator to sort the keys with
230       * @return a new, empty {@code TreeMap}
231       */
232      public static <C, K extends C, V> TreeMap<K, V> newTreeMap(
233          @Nullable Comparator<C> comparator) {
234        // Ideally, the extra type parameter "C" shouldn't be necessary. It is a
235        // work-around of a compiler type inference quirk that prevents the
236        // following code from being compiled:
237        // Comparator<Class<?>> comparator = null;
238        // Map<Class<? extends Throwable>, String> map = newTreeMap(comparator);
239        return new TreeMap<K, V>(comparator);
240      }
241    
242      /**
243       * Creates an {@code EnumMap} instance.
244       *
245       * @param type the key type for this map
246       * @return a new, empty {@code EnumMap}
247       */
248      public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Class<K> type) {
249        return new EnumMap<K, V>(checkNotNull(type));
250      }
251    
252      /**
253       * Creates an {@code EnumMap} with the same mappings as the specified map.
254       *
255       * @param map the map from which to initialize this {@code EnumMap}
256       * @return a new {@code EnumMap} initialized with the mappings from {@code
257       *         map}
258       * @throws IllegalArgumentException if {@code m} is not an {@code EnumMap}
259       *         instance and contains no mappings
260       */
261      public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(
262          Map<K, ? extends V> map) {
263        return new EnumMap<K, V>(map);
264      }
265    
266      /**
267       * Creates an {@code IdentityHashMap} instance.
268       *
269       * @return a new, empty {@code IdentityHashMap}
270       */
271      public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() {
272        return new IdentityHashMap<K, V>();
273      }
274    
275      /**
276       * Computes the difference between two maps. This difference is an immutable
277       * snapshot of the state of the maps at the time this method is called. It
278       * will never change, even if the maps change at a later time.
279       *
280       * <p>Since this method uses {@code HashMap} instances internally, the keys of
281       * the supplied maps must be well-behaved with respect to
282       * {@link Object#equals} and {@link Object#hashCode}.
283       *
284       * <p><b>Note:</b>If you only need to know whether two maps have the same
285       * mappings, call {@code left.equals(right)} instead of this method.
286       *
287       * @param left the map to treat as the "left" map for purposes of comparison
288       * @param right the map to treat as the "right" map for purposes of comparison
289       * @return the difference between the two maps
290       */
291      @SuppressWarnings("unchecked")
292      public static <K, V> MapDifference<K, V> difference(
293          Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right) {
294        if (left instanceof SortedMap) {
295          SortedMap<K, ? extends V> sortedLeft = (SortedMap<K, ? extends V>) left;
296          SortedMapDifference<K, V> result = difference(sortedLeft, right);
297          return result;
298        }
299        return difference(left, right, Equivalence.equals());
300      }
301    
302      /**
303       * Computes the difference between two maps. This difference is an immutable
304       * snapshot of the state of the maps at the time this method is called. It
305       * will never change, even if the maps change at a later time.
306       *
307       * <p>Values are compared using a provided equivalence, in the case of
308       * equality, the value on the 'left' is returned in the difference.
309       *
310       * <p>Since this method uses {@code HashMap} instances internally, the keys of
311       * the supplied maps must be well-behaved with respect to
312       * {@link Object#equals} and {@link Object#hashCode}.
313       *
314       * @param left the map to treat as the "left" map for purposes of comparison
315       * @param right the map to treat as the "right" map for purposes of comparison
316       * @param valueEquivalence the equivalence relationship to use to compare
317       *    values
318       * @return the difference between the two maps
319       * @since 10.0
320       */
321      @Beta
322      public static <K, V> MapDifference<K, V> difference(
323          Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right,
324          Equivalence<? super V> valueEquivalence) {
325        Preconditions.checkNotNull(valueEquivalence);
326    
327        Map<K, V> onlyOnLeft = newHashMap();
328        Map<K, V> onlyOnRight = new HashMap<K, V>(right); // will whittle it down
329        Map<K, V> onBoth = newHashMap();
330        Map<K, MapDifference.ValueDifference<V>> differences = newHashMap();
331        boolean eq = true;
332    
333        for (Entry<? extends K, ? extends V> entry : left.entrySet()) {
334          K leftKey = entry.getKey();
335          V leftValue = entry.getValue();
336          if (right.containsKey(leftKey)) {
337            V rightValue = onlyOnRight.remove(leftKey);
338            if (valueEquivalence.equivalent(leftValue, rightValue)) {
339              onBoth.put(leftKey, leftValue);
340            } else {
341              eq = false;
342              differences.put(
343                  leftKey, ValueDifferenceImpl.create(leftValue, rightValue));
344            }
345          } else {
346            eq = false;
347            onlyOnLeft.put(leftKey, leftValue);
348          }
349        }
350    
351        boolean areEqual = eq && onlyOnRight.isEmpty();
352        return mapDifference(
353            areEqual, onlyOnLeft, onlyOnRight, onBoth, differences);
354      }
355    
356      private static <K, V> MapDifference<K, V> mapDifference(boolean areEqual,
357          Map<K, V> onlyOnLeft, Map<K, V> onlyOnRight, Map<K, V> onBoth,
358          Map<K, ValueDifference<V>> differences) {
359        return new MapDifferenceImpl<K, V>(areEqual,
360            Collections.unmodifiableMap(onlyOnLeft),
361            Collections.unmodifiableMap(onlyOnRight),
362            Collections.unmodifiableMap(onBoth),
363            Collections.unmodifiableMap(differences));
364      }
365    
366      static class MapDifferenceImpl<K, V> implements MapDifference<K, V> {
367        final boolean areEqual;
368        final Map<K, V> onlyOnLeft;
369        final Map<K, V> onlyOnRight;
370        final Map<K, V> onBoth;
371        final Map<K, ValueDifference<V>> differences;
372    
373        MapDifferenceImpl(boolean areEqual, Map<K, V> onlyOnLeft,
374            Map<K, V> onlyOnRight, Map<K, V> onBoth,
375            Map<K, ValueDifference<V>> differences) {
376          this.areEqual = areEqual;
377          this.onlyOnLeft = onlyOnLeft;
378          this.onlyOnRight = onlyOnRight;
379          this.onBoth = onBoth;
380          this.differences = differences;
381        }
382    
383        public boolean areEqual() {
384          return areEqual;
385        }
386    
387        public Map<K, V> entriesOnlyOnLeft() {
388          return onlyOnLeft;
389        }
390    
391        public Map<K, V> entriesOnlyOnRight() {
392          return onlyOnRight;
393        }
394    
395        public Map<K, V> entriesInCommon() {
396          return onBoth;
397        }
398    
399        public Map<K, ValueDifference<V>> entriesDiffering() {
400          return differences;
401        }
402    
403        @Override
404        public boolean equals(Object object) {
405          if (object == this) {
406            return true;
407          }
408          if (object instanceof MapDifference) {
409            MapDifference<?, ?> other = (MapDifference<?, ?>) object;
410            return entriesOnlyOnLeft().equals(other.entriesOnlyOnLeft())
411                && entriesOnlyOnRight().equals(other.entriesOnlyOnRight())
412                && entriesInCommon().equals(other.entriesInCommon())
413                && entriesDiffering().equals(other.entriesDiffering());
414          }
415          return false;
416        }
417    
418        @Override
419        public int hashCode() {
420          return Objects.hashCode(entriesOnlyOnLeft(), entriesOnlyOnRight(),
421              entriesInCommon(), entriesDiffering());
422        }
423    
424        @Override
425        public String toString() {
426          if (areEqual) {
427            return "equal";
428          }
429    
430          StringBuilder result = new StringBuilder("not equal");
431          if (!onlyOnLeft.isEmpty()) {
432            result.append(": only on left=").append(onlyOnLeft);
433          }
434          if (!onlyOnRight.isEmpty()) {
435            result.append(": only on right=").append(onlyOnRight);
436          }
437          if (!differences.isEmpty()) {
438            result.append(": value differences=").append(differences);
439          }
440          return result.toString();
441        }
442      }
443    
444      static class ValueDifferenceImpl<V>
445          implements MapDifference.ValueDifference<V> {
446        private final V left;
447        private final V right;
448    
449        static <V> ValueDifference<V> create(@Nullable V left, @Nullable V right) {
450          return new ValueDifferenceImpl<V>(left, right);
451        }
452    
453        private ValueDifferenceImpl(@Nullable V left, @Nullable V right) {
454          this.left = left;
455          this.right = right;
456        }
457    
458        public V leftValue() {
459          return left;
460        }
461    
462        public V rightValue() {
463          return right;
464        }
465    
466        @Override
467        public boolean equals(@Nullable Object object) {
468          if (object instanceof MapDifference.ValueDifference) {
469            MapDifference.ValueDifference<?> that =
470                (MapDifference.ValueDifference<?>) object;
471            return Objects.equal(this.left, that.leftValue())
472                && Objects.equal(this.right, that.rightValue());
473          }
474          return false;
475        }
476    
477        @Override
478        public int hashCode() {
479          return Objects.hashCode(left, right);
480        }
481    
482        @Override
483        public String toString() {
484          return "(" + left + ", " + right + ")";
485        }
486      }
487    
488      /**
489       * Computes the difference between two sorted maps, using the comparator of
490       * the left map, or {@code Ordering.natural()} if the left map uses the
491       * natural ordering of its elements. This difference is an immutable snapshot
492       * of the state of the maps at the time this method is called. It will never
493       * change, even if the maps change at a later time.
494       *
495       * <p>Since this method uses {@code TreeMap} instances internally, the keys of
496       * the right map must all compare as distinct according to the comparator
497       * of the left map.
498       *
499       * <p><b>Note:</b>If you only need to know whether two sorted maps have the
500       * same mappings, call {@code left.equals(right)} instead of this method.
501       *
502       * @param left the map to treat as the "left" map for purposes of comparison
503       * @param right the map to treat as the "right" map for purposes of comparison
504       * @return the difference between the two maps
505       * @since 11.0
506       */
507      public static <K, V> SortedMapDifference<K, V> difference(
508          SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right) {
509        checkNotNull(left);
510        checkNotNull(right);
511        Comparator<? super K> comparator = orNaturalOrder(left.comparator());
512        SortedMap<K, V> onlyOnLeft = Maps.newTreeMap(comparator);
513        SortedMap<K, V> onlyOnRight = Maps.newTreeMap(comparator);
514        onlyOnRight.putAll(right); // will whittle it down
515        SortedMap<K, V> onBoth = Maps.newTreeMap(comparator);
516        SortedMap<K, MapDifference.ValueDifference<V>> differences =
517            Maps.newTreeMap(comparator);
518        boolean eq = true;
519    
520        for (Entry<? extends K, ? extends V> entry : left.entrySet()) {
521          K leftKey = entry.getKey();
522          V leftValue = entry.getValue();
523          if (right.containsKey(leftKey)) {
524            V rightValue = onlyOnRight.remove(leftKey);
525            if (Objects.equal(leftValue, rightValue)) {
526              onBoth.put(leftKey, leftValue);
527            } else {
528              eq = false;
529              differences.put(
530                  leftKey, ValueDifferenceImpl.create(leftValue, rightValue));
531            }
532          } else {
533            eq = false;
534            onlyOnLeft.put(leftKey, leftValue);
535          }
536        }
537    
538        boolean areEqual = eq && onlyOnRight.isEmpty();
539        return sortedMapDifference(
540            areEqual, onlyOnLeft, onlyOnRight, onBoth, differences);
541      }
542    
543      private static <K, V> SortedMapDifference<K, V> sortedMapDifference(
544          boolean areEqual, SortedMap<K, V> onlyOnLeft, SortedMap<K, V> onlyOnRight,
545          SortedMap<K, V> onBoth, SortedMap<K, ValueDifference<V>> differences) {
546        return new SortedMapDifferenceImpl<K, V>(areEqual,
547            Collections.unmodifiableSortedMap(onlyOnLeft),
548            Collections.unmodifiableSortedMap(onlyOnRight),
549            Collections.unmodifiableSortedMap(onBoth),
550            Collections.unmodifiableSortedMap(differences));
551      }
552    
553      static class SortedMapDifferenceImpl<K, V> extends MapDifferenceImpl<K, V>
554          implements SortedMapDifference<K, V> {
555        SortedMapDifferenceImpl(boolean areEqual, SortedMap<K, V> onlyOnLeft,
556            SortedMap<K, V> onlyOnRight, SortedMap<K, V> onBoth,
557            SortedMap<K, ValueDifference<V>> differences) {
558          super(areEqual, onlyOnLeft, onlyOnRight, onBoth, differences);
559        }
560    
561        @Override
562        public SortedMap<K, ValueDifference<V>> entriesDiffering() {
563          return (SortedMap<K, ValueDifference<V>>) super.entriesDiffering();
564        }
565    
566        @Override
567        public SortedMap<K, V> entriesInCommon() {
568          return (SortedMap<K, V>) super.entriesInCommon();
569        }
570    
571        @Override
572        public SortedMap<K, V> entriesOnlyOnLeft() {
573          return (SortedMap<K, V>) super.entriesOnlyOnLeft();
574        }
575    
576        @Override
577        public SortedMap<K, V> entriesOnlyOnRight() {
578          return (SortedMap<K, V>) super.entriesOnlyOnRight();
579        }
580      }
581    
582      /**
583       * Returns the specified comparator if not null; otherwise returns {@code
584       * Ordering.natural()}. This method is an abomination of generics; the only
585       * purpose of this method is to contain the ugly type-casting in one place.
586       */
587      @SuppressWarnings("unchecked")
588      static <E> Comparator<? super E> orNaturalOrder(
589          @Nullable Comparator<? super E> comparator) {
590        if (comparator != null) { // can't use ? : because of javac bug 5080917
591          return comparator;
592        }
593        return (Comparator<E>) Ordering.natural();
594      }
595    
596      /**
597       * Returns a view of the set as a map, mapping keys from the set according to
598       * the specified function.
599       *
600       * <p>Specifically, for each {@code k} in the backing set, the returned map
601       * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code
602       * keySet}, {@code values}, and {@code entrySet} views of the returned map
603       * iterate in the same order as the backing set.
604       *
605       * <p>Modifications to the backing set are read through to the returned map.
606       * The returned map supports removal operations if the backing set does.
607       * Removal operations write through to the backing set.  The returned map
608       * does not support put operations.
609       *
610       * <p><b>Warning</b>: If the function rejects {@code null}, caution is
611       * required to make sure the set does not contain {@code null}, because the
612       * view cannot stop {@code null} from being added to the set.
613       *
614       * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
615       * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also
616       * of type {@code K}. Using a key type for which this may not hold, such as
617       * {@code ArrayList}, may risk a {@code ClassCastException} when calling
618       * methods on the resulting map view.
619       */
620      @Beta
621      static <K, V> Map<K, V> asMap(
622          Set<K> set, Function<? super K, V> function) {
623        if (set instanceof SortedSet) {
624          return asMap((SortedSet<K>) set, function);
625        } else {
626          return new AsMapView<K, V>(set, function);
627        }
628      }
629    
630      /**
631       * Returns a view of the sorted set as a map, mapping keys from the set
632       * according to the specified function.
633       *
634       * <p>Specifically, for each {@code k} in the backing set, the returned map
635       * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code
636       * keySet}, {@code values}, and {@code entrySet} views of the returned map
637       * iterate in the same order as the backing set.
638       *
639       * <p>Modifications to the backing set are read through to the returned map.
640       * The returned map supports removal operations if the backing set does.
641       * Removal operations write through to the backing set.  The returned map does
642       * not support put operations.
643       *
644       * <p><b>Warning</b>: If the function rejects {@code null}, caution is
645       * required to make sure the set does not contain {@code null}, because the
646       * view cannot stop {@code null} from being added to the set.
647       *
648       * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
649       * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
650       * type {@code K}. Using a key type for which this may not hold, such as
651       * {@code ArrayList}, may risk a {@code ClassCastException} when calling
652       * methods on the resulting map view.
653       */
654      @Beta
655      static <K, V> SortedMap<K, V> asMap(
656          SortedSet<K> set, Function<? super K, V> function) {
657        // TODO: NavigableSet overloads
658        return new SortedAsMapView<K, V>(set, function);
659      }
660    
661      private static class AsMapView<K, V> extends ImprovedAbstractMap<K, V> {
662    
663        private final Set<K> set;
664        final Function<? super K, V> function;
665    
666        Set<K> backingSet() {
667          return set;
668        }
669    
670        AsMapView(Set<K> set, Function<? super K, V> function) {
671          this.set = checkNotNull(set);
672          this.function = checkNotNull(function);
673        }
674    
675        @Override
676        public Set<K> keySet() {
677          // probably not worth caching
678          return new ForwardingSet<K>() {
679            @Override
680            protected Set<K> delegate() {
681              return set;
682            }
683    
684            @Override
685            public boolean add(K element) {
686              throw new UnsupportedOperationException();
687            }
688    
689            @Override
690            public boolean addAll(Collection<? extends K> collection) {
691              throw new UnsupportedOperationException();
692            }
693          };
694        }
695    
696        @Override
697        public Collection<V> values() {
698          // probably not worth caching
699          return Collections2.transform(set, function);
700        }
701    
702        @Override
703        public int size() {
704          return set.size();
705        }
706    
707        @Override
708        public boolean containsKey(@Nullable Object key) {
709          return set.contains(key);
710        }
711    
712        @Override
713        public V get(@Nullable Object key) {
714          if (set.contains(key)) {
715            @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
716            K k = (K) key;
717            return function.apply(k);
718          } else {
719            return null;
720          }
721        }
722    
723        @Override
724        public V remove(@Nullable Object key) {
725          if (set.remove(key)) {
726            @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
727            K k = (K) key;
728            return function.apply(k);
729          } else {
730            return null;
731          }
732        }
733    
734        @Override
735        public void clear() {
736          set.clear();
737        }
738    
739        @Override
740        protected Set<Entry<K, V>> createEntrySet() {
741          return new EntrySet<K, V>() {
742            @Override
743            Map<K, V> map() {
744              return AsMapView.this;
745            }
746    
747            @Override
748            public Iterator<Entry<K, V>> iterator() {
749              final Iterator<K> backingIterator = set.iterator();
750              return new Iterator<Entry<K, V>>() {
751                public boolean hasNext() {
752                  return backingIterator.hasNext();
753                }
754    
755                public Entry<K, V> next() {
756                  K k = backingIterator.next();
757                  return Maps.immutableEntry(k, function.apply(k));
758                }
759    
760                public void remove() {
761                  backingIterator.remove();
762                }
763              };
764            }
765          };
766        }
767      }
768    
769      private static final class SortedAsMapView<K, V> extends AsMapView<K, V>
770          implements SortedMap<K, V> {
771    
772        SortedAsMapView(SortedSet<K> set, Function<? super K, V> function) {
773          super(set, function);
774        }
775    
776        public Comparator<? super K> comparator() {
777          return backingSet().comparator();
778        }
779    
780        public SortedMap<K, V> subMap(K fromKey, K toKey) {
781          return asMap(backingSet().subSet(fromKey, toKey), function);
782        }
783    
784        public SortedMap<K, V> headMap(K toKey) {
785          return asMap(backingSet().headSet(toKey), function);
786        }
787    
788        public SortedMap<K, V> tailMap(K fromKey) {
789          return asMap(backingSet().tailSet(fromKey), function);
790        }
791    
792        public K firstKey() {
793          return backingSet().first();
794        }
795    
796        public K lastKey() {
797          return backingSet().last();
798        }
799    
800        @Override
801        SortedSet<K> backingSet() {
802          return (SortedSet<K>) super.backingSet();
803        }
804      }
805    
806      /**
807       * Returns an immutable map for which the {@link Map#values} are the given
808       * elements in the given order, and each key is the product of invoking a
809       * supplied function on its corresponding value.
810       *
811       * @param values the values to use when constructing the {@code Map}
812       * @param keyFunction the function used to produce the key for each value
813       * @return a map mapping the result of evaluating the function {@code
814       *         keyFunction} on each value in the input collection to that value
815       * @throws IllegalArgumentException if {@code keyFunction} produces the same
816       *         key for more than one value in the input collection
817       * @throws NullPointerException if any elements of {@code values} is null, or
818       *         if {@code keyFunction} produces {@code null} for any value
819       */
820      public static <K, V> ImmutableMap<K, V> uniqueIndex(
821          Iterable<V> values, Function<? super V, K> keyFunction) {
822        return uniqueIndex(values.iterator(), keyFunction);
823      }
824    
825      /**
826       * Returns an immutable map for which the {@link Map#values} are the given
827       * elements in the given order, and each key is the product of invoking a
828       * supplied function on its corresponding value.
829       *
830       * @param values the values to use when constructing the {@code Map}
831       * @param keyFunction the function used to produce the key for each value
832       * @return a map mapping the result of evaluating the function {@code
833       *         keyFunction} on each value in the input collection to that value
834       * @throws IllegalArgumentException if {@code keyFunction} produces the same
835       *         key for more than one value in the input collection
836       * @throws NullPointerException if any elements of {@code values} is null, or
837       *         if {@code keyFunction} produces {@code null} for any value
838       * @since 10.0
839       */
840      public static <K, V> ImmutableMap<K, V> uniqueIndex(
841          Iterator<V> values, Function<? super V, K> keyFunction) {
842        checkNotNull(keyFunction);
843        ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
844        while (values.hasNext()) {
845          V value = values.next();
846          builder.put(keyFunction.apply(value), value);
847        }
848        return builder.build();
849      }
850    
851      /**
852       * Creates an {@code ImmutableMap<String, String>} from a {@code Properties}
853       * instance. Properties normally derive from {@code Map<Object, Object>}, but
854       * they typically contain strings, which is awkward. This method lets you get
855       * a plain-old-{@code Map} out of a {@code Properties}.
856       *
857       * @param properties a {@code Properties} object to be converted
858       * @return an immutable map containing all the entries in {@code properties}
859       * @throws ClassCastException if any key in {@code Properties} is not a {@code
860       *         String}
861       * @throws NullPointerException if any key or value in {@code Properties} is
862       *         null
863       */
864      @GwtIncompatible("java.util.Properties")
865      public static ImmutableMap<String, String> fromProperties(
866          Properties properties) {
867        ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
868    
869        for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) {
870          String key = (String) e.nextElement();
871          builder.put(key, properties.getProperty(key));
872        }
873    
874        return builder.build();
875      }
876    
877      /**
878       * Returns an immutable map entry with the specified key and value. The {@link
879       * Entry#setValue} operation throws an {@link UnsupportedOperationException}.
880       *
881       * <p>The returned entry is serializable.
882       *
883       * @param key the key to be associated with the returned entry
884       * @param value the value to be associated with the returned entry
885       */
886      @GwtCompatible(serializable = true)
887      public static <K, V> Entry<K, V> immutableEntry(
888          @Nullable K key, @Nullable V value) {
889        return new ImmutableEntry<K, V>(key, value);
890      }
891    
892      /**
893       * Returns an unmodifiable view of the specified set of entries. The {@link
894       * Entry#setValue} operation throws an {@link UnsupportedOperationException},
895       * as do any operations that would modify the returned set.
896       *
897       * @param entrySet the entries for which to return an unmodifiable view
898       * @return an unmodifiable view of the entries
899       */
900      static <K, V> Set<Entry<K, V>> unmodifiableEntrySet(
901          Set<Entry<K, V>> entrySet) {
902        return new UnmodifiableEntrySet<K, V>(
903            Collections.unmodifiableSet(entrySet));
904      }
905    
906      /**
907       * Returns an unmodifiable view of the specified map entry. The {@link
908       * Entry#setValue} operation throws an {@link UnsupportedOperationException}.
909       * This also has the side-effect of redefining {@code equals} to comply with
910       * the Entry contract, to avoid a possible nefarious implementation of equals.
911       *
912       * @param entry the entry for which to return an unmodifiable view
913       * @return an unmodifiable view of the entry
914       */
915      static <K, V> Entry<K, V> unmodifiableEntry(final Entry<K, V> entry) {
916        checkNotNull(entry);
917        return new AbstractMapEntry<K, V>() {
918          @Override
919          public K getKey() {
920            return entry.getKey();
921          }
922    
923          @Override
924          public V getValue() {
925            return entry.getValue();
926          }
927        };
928      }
929    
930      /** @see Multimaps#unmodifiableEntries */
931      static class UnmodifiableEntries<K, V>
932          extends ForwardingCollection<Entry<K, V>> {
933        private final Collection<Entry<K, V>> entries;
934    
935        UnmodifiableEntries(Collection<Entry<K, V>> entries) {
936          this.entries = entries;
937        }
938    
939        @Override
940        protected Collection<Entry<K, V>> delegate() {
941          return entries;
942        }
943    
944        @Override
945        public Iterator<Entry<K, V>> iterator() {
946          final Iterator<Entry<K, V>> delegate = super.iterator();
947          return new ForwardingIterator<Entry<K, V>>() {
948            @Override
949            public Entry<K, V> next() {
950              return unmodifiableEntry(super.next());
951            }
952    
953            @Override
954            public void remove() {
955              throw new UnsupportedOperationException();
956            }
957    
958            @Override
959            protected Iterator<Entry<K, V>> delegate() {
960              return delegate;
961            }
962          };
963        }
964    
965        // See java.util.Collections.UnmodifiableEntrySet for details on attacks.
966    
967        @Override
968        public boolean add(Entry<K, V> element) {
969          throw new UnsupportedOperationException();
970        }
971    
972        @Override
973        public boolean addAll(
974            Collection<? extends Entry<K, V>> collection) {
975          throw new UnsupportedOperationException();
976        }
977    
978        @Override
979        public void clear() {
980          throw new UnsupportedOperationException();
981        }
982    
983        @Override
984        public boolean remove(Object object) {
985          throw new UnsupportedOperationException();
986        }
987    
988        @Override
989        public boolean removeAll(Collection<?> collection) {
990          throw new UnsupportedOperationException();
991        }
992    
993        @Override
994        public boolean retainAll(Collection<?> collection) {
995          throw new UnsupportedOperationException();
996        }
997    
998        @Override
999        public Object[] toArray() {
1000          return standardToArray();
1001        }
1002    
1003        @Override
1004        public <T> T[] toArray(T[] array) {
1005          return standardToArray(array);
1006        }
1007      }
1008    
1009      /** @see Maps#unmodifiableEntrySet(Set) */
1010      static class UnmodifiableEntrySet<K, V>
1011          extends UnmodifiableEntries<K, V> implements Set<Entry<K, V>> {
1012        UnmodifiableEntrySet(Set<Entry<K, V>> entries) {
1013          super(entries);
1014        }
1015    
1016        // See java.util.Collections.UnmodifiableEntrySet for details on attacks.
1017    
1018        @Override
1019        public boolean equals(@Nullable Object object) {
1020          return Sets.equalsImpl(this, object);
1021        }
1022    
1023        @Override
1024        public int hashCode() {
1025          return Sets.hashCodeImpl(this);
1026        }
1027      }
1028    
1029      /**
1030       * Returns a synchronized (thread-safe) bimap backed by the specified bimap.
1031       * In order to guarantee serial access, it is critical that <b>all</b> access
1032       * to the backing bimap is accomplished through the returned bimap.
1033       *
1034       * <p>It is imperative that the user manually synchronize on the returned map
1035       * when accessing any of its collection views: <pre>   {@code
1036       *
1037       *   BiMap<Long, String> map = Maps.synchronizedBiMap(
1038       *       HashBiMap.<Long, String>create());
1039       *   ...
1040       *   Set<Long> set = map.keySet();  // Needn't be in synchronized block
1041       *   ...
1042       *   synchronized (map) {  // Synchronizing on map, not set!
1043       *     Iterator<Long> it = set.iterator(); // Must be in synchronized block
1044       *     while (it.hasNext()) {
1045       *       foo(it.next());
1046       *     }
1047       *   }}</pre>
1048       *
1049       * Failure to follow this advice may result in non-deterministic behavior.
1050       *
1051       * <p>The returned bimap will be serializable if the specified bimap is
1052       * serializable.
1053       *
1054       * @param bimap the bimap to be wrapped in a synchronized view
1055       * @return a sychronized view of the specified bimap
1056       */
1057      public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
1058        return Synchronized.biMap(bimap, null);
1059      }
1060    
1061      /**
1062       * Returns an unmodifiable view of the specified bimap. This method allows
1063       * modules to provide users with "read-only" access to internal bimaps. Query
1064       * operations on the returned bimap "read through" to the specified bimap, and
1065       * attempts to modify the returned map, whether direct or via its collection
1066       * views, result in an {@code UnsupportedOperationException}.
1067       *
1068       * <p>The returned bimap will be serializable if the specified bimap is
1069       * serializable.
1070       *
1071       * @param bimap the bimap for which an unmodifiable view is to be returned
1072       * @return an unmodifiable view of the specified bimap
1073       */
1074      public static <K, V> BiMap<K, V> unmodifiableBiMap(
1075          BiMap<? extends K, ? extends V> bimap) {
1076        return new UnmodifiableBiMap<K, V>(bimap, null);
1077      }
1078    
1079      /** @see Maps#unmodifiableBiMap(BiMap) */
1080      private static class UnmodifiableBiMap<K, V>
1081          extends ForwardingMap<K, V> implements BiMap<K, V>, Serializable {
1082        final Map<K, V> unmodifiableMap;
1083        final BiMap<? extends K, ? extends V> delegate;
1084        BiMap<V, K> inverse;
1085        transient Set<V> values;
1086    
1087        UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate,
1088            @Nullable BiMap<V, K> inverse) {
1089          unmodifiableMap = Collections.unmodifiableMap(delegate);
1090          this.delegate = delegate;
1091          this.inverse = inverse;
1092        }
1093    
1094        @Override
1095        protected Map<K, V> delegate() {
1096          return unmodifiableMap;
1097        }
1098    
1099        public V forcePut(K key, V value) {
1100          throw new UnsupportedOperationException();
1101        }
1102    
1103        public BiMap<V, K> inverse() {
1104          BiMap<V, K> result = inverse;
1105          return (result == null)
1106              ? inverse = new UnmodifiableBiMap<V, K>(delegate.inverse(), this)
1107              : result;
1108        }
1109    
1110        @Override
1111        public Set<V> values() {
1112          Set<V> result = values;
1113          return (result == null)
1114              ? values = Collections.unmodifiableSet(delegate.values())
1115              : result;
1116        }
1117    
1118        private static final long serialVersionUID = 0;
1119      }
1120    
1121      /**
1122       * Returns a view of a map where each value is transformed by a function. All
1123       * other properties of the map, such as iteration order, are left intact. For
1124       * example, the code: <pre>   {@code
1125       *
1126       *   Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9);
1127       *   Function<Integer, Double> sqrt =
1128       *       new Function<Integer, Double>() {
1129       *         public Double apply(Integer in) {
1130       *           return Math.sqrt((int) in);
1131       *         }
1132       *       };
1133       *   Map<String, Double> transformed = Maps.transformValues(map, sqrt);
1134       *   System.out.println(transformed);}</pre>
1135       *
1136       * ... prints {@code {a=2.0, b=3.0}}.
1137       *
1138       * <p>Changes in the underlying map are reflected in this view. Conversely,
1139       * this view supports removal operations, and these are reflected in the
1140       * underlying map.
1141       *
1142       * <p>It's acceptable for the underlying map to contain null keys, and even
1143       * null values provided that the function is capable of accepting null input.
1144       * The transformed map might contain null values, if the function sometimes
1145       * gives a null result.
1146       *
1147       * <p>The returned map is not thread-safe or serializable, even if the
1148       * underlying map is.
1149       *
1150       * <p>The function is applied lazily, invoked when needed. This is necessary
1151       * for the returned map to be a view, but it means that the function will be
1152       * applied many times for bulk operations like {@link Map#containsValue} and
1153       * {@code Map.toString()}. For this to perform well, {@code function} should
1154       * be fast. To avoid lazy evaluation when the returned map doesn't need to be
1155       * a view, copy the returned map into a new map of your choosing.
1156       */
1157      public static <K, V1, V2> Map<K, V2> transformValues(
1158          Map<K, V1> fromMap, Function<? super V1, V2> function) {
1159        return transformEntries(fromMap, asEntryTransformer(function));
1160      }
1161    
1162      /**
1163       * Returns a view of a sorted map where each value is transformed by a
1164       * function. All other properties of the map, such as iteration order, are
1165       * left intact. For example, the code: <pre>   {@code
1166       *
1167       *   SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
1168       *   Function<Integer, Double> sqrt =
1169       *       new Function<Integer, Double>() {
1170       *         public Double apply(Integer in) {
1171       *           return Math.sqrt((int) in);
1172       *         }
1173       *       };
1174       *   SortedMap<String, Double> transformed =
1175       *        Maps.transformSortedValues(map, sqrt);
1176       *   System.out.println(transformed);}</pre>
1177       *
1178       * ... prints {@code {a=2.0, b=3.0}}.
1179       *
1180       * <p>Changes in the underlying map are reflected in this view. Conversely,
1181       * this view supports removal operations, and these are reflected in the
1182       * underlying map.
1183       *
1184       * <p>It's acceptable for the underlying map to contain null keys, and even
1185       * null values provided that the function is capable of accepting null input.
1186       * The transformed map might contain null values, if the function sometimes
1187       * gives a null result.
1188       *
1189       * <p>The returned map is not thread-safe or serializable, even if the
1190       * underlying map is.
1191       *
1192       * <p>The function is applied lazily, invoked when needed. This is necessary
1193       * for the returned map to be a view, but it means that the function will be
1194       * applied many times for bulk operations like {@link Map#containsValue} and
1195       * {@code Map.toString()}. For this to perform well, {@code function} should
1196       * be fast. To avoid lazy evaluation when the returned map doesn't need to be
1197       * a view, copy the returned map into a new map of your choosing.
1198       *
1199       * @since 11.0
1200       */
1201      @Beta
1202      public static <K, V1, V2> SortedMap<K, V2> transformValues(
1203          SortedMap<K, V1> fromMap, Function<? super V1, V2> function) {
1204        return transformEntries(fromMap, asEntryTransformer(function));
1205      }
1206    
1207      private static <K, V1, V2> EntryTransformer<K, V1, V2>
1208          asEntryTransformer(final Function<? super V1, V2> function) {
1209        checkNotNull(function);
1210        return new EntryTransformer<K, V1, V2>() {
1211          public V2 transformEntry(K key, V1 value) {
1212            return function.apply(value);
1213          }
1214        };
1215      }
1216    
1217      /**
1218       * Returns a view of a map whose values are derived from the original map's
1219       * entries. In contrast to {@link #transformValues}, this method's
1220       * entry-transformation logic may depend on the key as well as the value.
1221       *
1222       * <p>All other properties of the transformed map, such as iteration order,
1223       * are left intact. For example, the code: <pre>   {@code
1224       *
1225       *   Map<String, Boolean> options =
1226       *       ImmutableMap.of("verbose", true, "sort", false);
1227       *   EntryTransformer<String, Boolean, String> flagPrefixer =
1228       *       new EntryTransformer<String, Boolean, String>() {
1229       *         public String transformEntry(String key, Boolean value) {
1230       *           return value ? key : "no" + key;
1231       *         }
1232       *       };
1233       *   Map<String, String> transformed =
1234       *       Maps.transformEntries(options, flagPrefixer);
1235       *   System.out.println(transformed);}</pre>
1236       *
1237       * ... prints {@code {verbose=verbose, sort=nosort}}.
1238       *
1239       * <p>Changes in the underlying map are reflected in this view. Conversely,
1240       * this view supports removal operations, and these are reflected in the
1241       * underlying map.
1242       *
1243       * <p>It's acceptable for the underlying map to contain null keys and null
1244       * values provided that the transformer is capable of accepting null inputs.
1245       * The transformed map might contain null values if the transformer sometimes
1246       * gives a null result.
1247       *
1248       * <p>The returned map is not thread-safe or serializable, even if the
1249       * underlying map is.
1250       *
1251       * <p>The transformer is applied lazily, invoked when needed. This is
1252       * necessary for the returned map to be a view, but it means that the
1253       * transformer will be applied many times for bulk operations like {@link
1254       * Map#containsValue} and {@link Object#toString}. For this to perform well,
1255       * {@code transformer} should be fast. To avoid lazy evaluation when the
1256       * returned map doesn't need to be a view, copy the returned map into a new
1257       * map of your choosing.
1258       *
1259       * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
1260       * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
1261       * that {@code k2} is also of type {@code K}. Using an {@code
1262       * EntryTransformer} key type for which this may not hold, such as {@code
1263       * ArrayList}, may risk a {@code ClassCastException} when calling methods on
1264       * the transformed map.
1265       *
1266       * @since 7.0
1267       */
1268      public static <K, V1, V2> Map<K, V2> transformEntries(
1269          Map<K, V1> fromMap,
1270          EntryTransformer<? super K, ? super V1, V2> transformer) {
1271        if (fromMap instanceof SortedMap) {
1272          return transformEntries((SortedMap<K, V1>) fromMap, transformer);
1273        }
1274        return new TransformedEntriesMap<K, V1, V2>(fromMap, transformer);
1275      }
1276    
1277      /**
1278       * Returns a view of a sorted map whose values are derived from the original
1279       * sorted map's entries. In contrast to {@link #transformValues}, this
1280       * method's entry-transformation logic may depend on the key as well as the
1281       * value.
1282       *
1283       * <p>All other properties of the transformed map, such as iteration order,
1284       * are left intact. For example, the code: <pre>   {@code
1285       *
1286       *   Map<String, Boolean> options =
1287       *       ImmutableSortedMap.of("verbose", true, "sort", false);
1288       *   EntryTransformer<String, Boolean, String> flagPrefixer =
1289       *       new EntryTransformer<String, Boolean, String>() {
1290       *         public String transformEntry(String key, Boolean value) {
1291       *           return value ? key : "yes" + key;
1292       *         }
1293       *       };
1294       *   SortedMap<String, String> transformed =
1295       *       LabsMaps.transformSortedEntries(options, flagPrefixer);
1296       *   System.out.println(transformed);}</pre>
1297       *
1298       * ... prints {@code {sort=yessort, verbose=verbose}}.
1299       *
1300       * <p>Changes in the underlying map are reflected in this view. Conversely,
1301       * this view supports removal operations, and these are reflected in the
1302       * underlying map.
1303       *
1304       * <p>It's acceptable for the underlying map to contain null keys and null
1305       * values provided that the transformer is capable of accepting null inputs.
1306       * The transformed map might contain null values if the transformer sometimes
1307       * gives a null result.
1308       *
1309       * <p>The returned map is not thread-safe or serializable, even if the
1310       * underlying map is.
1311       *
1312       * <p>The transformer is applied lazily, invoked when needed. This is
1313       * necessary for the returned map to be a view, but it means that the
1314       * transformer will be applied many times for bulk operations like {@link
1315       * Map#containsValue} and {@link Object#toString}. For this to perform well,
1316       * {@code transformer} should be fast. To avoid lazy evaluation when the
1317       * returned map doesn't need to be a view, copy the returned map into a new
1318       * map of your choosing.
1319       *
1320       * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
1321       * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
1322       * that {@code k2} is also of type {@code K}. Using an {@code
1323       * EntryTransformer} key type for which this may not hold, such as {@code
1324       * ArrayList}, may risk a {@code ClassCastException} when calling methods on
1325       * the transformed map.
1326       *
1327       * @since 11.0
1328       */
1329      @Beta
1330      public static <K, V1, V2> SortedMap<K, V2> transformEntries(
1331          SortedMap<K, V1> fromMap,
1332          EntryTransformer<? super K, ? super V1, V2> transformer) {
1333        return new TransformedEntriesSortedMap<K, V1, V2>(fromMap, transformer);
1334      }
1335    
1336      /**
1337       * A transformation of the value of a key-value pair, using both key and value
1338       * as inputs. To apply the transformation to a map, use
1339       * {@link Maps#transformEntries(Map, EntryTransformer)}.
1340       *
1341       * @param <K> the key type of the input and output entries
1342       * @param <V1> the value type of the input entry
1343       * @param <V2> the value type of the output entry
1344       * @since 7.0
1345       */
1346      public interface EntryTransformer<K, V1, V2> {
1347        /**
1348         * Determines an output value based on a key-value pair. This method is
1349         * <i>generally expected</i>, but not absolutely required, to have the
1350         * following properties:
1351         *
1352         * <ul>
1353         * <li>Its execution does not cause any observable side effects.
1354         * <li>The computation is <i>consistent with equals</i>; that is,
1355         *     {@link Objects#equal Objects.equal}{@code (k1, k2) &&}
1356         *     {@link Objects#equal}{@code (v1, v2)} implies that {@code
1357         *     Objects.equal(transformer.transform(k1, v1),
1358         *     transformer.transform(k2, v2))}.
1359         * </ul>
1360         *
1361         * @throws NullPointerException if the key or value is null and this
1362         *     transformer does not accept null arguments
1363         */
1364        V2 transformEntry(@Nullable K key, @Nullable V1 value);
1365      }
1366    
1367      static class TransformedEntriesMap<K, V1, V2>
1368          extends AbstractMap<K, V2> {
1369        final Map<K, V1> fromMap;
1370        final EntryTransformer<? super K, ? super V1, V2> transformer;
1371    
1372        TransformedEntriesMap(
1373            Map<K, V1> fromMap,
1374            EntryTransformer<? super K, ? super V1, V2> transformer) {
1375          this.fromMap = checkNotNull(fromMap);
1376          this.transformer = checkNotNull(transformer);
1377        }
1378    
1379        @Override
1380        public int size() {
1381          return fromMap.size();
1382        }
1383    
1384        @Override
1385        public boolean containsKey(Object key) {
1386          return fromMap.containsKey(key);
1387        }
1388    
1389        // safe as long as the user followed the <b>Warning</b> in the javadoc
1390        @Override
1391        @SuppressWarnings("unchecked")
1392        public V2 get(Object key) {
1393          V1 value = fromMap.get(key);
1394          return (value != null || fromMap.containsKey(key))
1395              ? transformer.transformEntry((K) key, value)
1396              : null;
1397        }
1398    
1399        // safe as long as the user followed the <b>Warning</b> in the javadoc
1400        @Override
1401        @SuppressWarnings("unchecked")
1402        public V2 remove(Object key) {
1403          return fromMap.containsKey(key)
1404              ? transformer.transformEntry((K) key, fromMap.remove(key))
1405              : null;
1406        }
1407    
1408        @Override
1409        public void clear() {
1410          fromMap.clear();
1411        }
1412    
1413        @Override
1414        public Set<K> keySet() {
1415          return fromMap.keySet();
1416        }
1417    
1418        Set<Entry<K, V2>> entrySet;
1419    
1420        @Override
1421        public Set<Entry<K, V2>> entrySet() {
1422          Set<Entry<K, V2>> result = entrySet;
1423          if (result == null) {
1424            entrySet = result = new EntrySet<K, V2>() {
1425              @Override
1426              Map<K, V2> map() {
1427                return TransformedEntriesMap.this;
1428              }
1429    
1430              @Override
1431              public Iterator<Entry<K, V2>> iterator() {
1432                return new TransformedIterator<Entry<K, V1>, Entry<K, V2>>(
1433                    fromMap.entrySet().iterator()) {
1434                  @Override
1435                  Entry<K, V2> transform(final Entry<K, V1> entry) {
1436                    return new AbstractMapEntry<K, V2>() {
1437                      @Override
1438                      public K getKey() {
1439                        return entry.getKey();
1440                      }
1441    
1442                      @Override
1443                      public V2 getValue() {
1444                        return transformer.transformEntry(entry.getKey(), entry.getValue());
1445                      }
1446                    };
1447                  }
1448                };
1449              }
1450            };
1451          }
1452          return result;
1453        }
1454    
1455        Collection<V2> values;
1456    
1457        @Override
1458        public Collection<V2> values() {
1459          Collection<V2> result = values;
1460          if (result == null) {
1461            return values = new Values<K, V2>() {
1462              @Override
1463              Map<K, V2> map() {
1464                return TransformedEntriesMap.this;
1465              }
1466            };
1467          }
1468          return result;
1469        }
1470      }
1471    
1472      static class TransformedEntriesSortedMap<K, V1, V2>
1473          extends TransformedEntriesMap<K, V1, V2> implements SortedMap<K, V2> {
1474    
1475        protected SortedMap<K, V1> fromMap() {
1476          return (SortedMap<K, V1>) fromMap;
1477        }
1478    
1479        TransformedEntriesSortedMap(SortedMap<K, V1> fromMap,
1480            EntryTransformer<? super K, ? super V1, V2> transformer) {
1481          super(fromMap, transformer);
1482        }
1483    
1484        public Comparator<? super K> comparator() {
1485          return fromMap().comparator();
1486        }
1487    
1488        public K firstKey() {
1489          return fromMap().firstKey();
1490        }
1491    
1492        public SortedMap<K, V2> headMap(K toKey) {
1493          return transformEntries(fromMap().headMap(toKey), transformer);
1494        }
1495    
1496        public K lastKey() {
1497          return fromMap().lastKey();
1498        }
1499    
1500        public SortedMap<K, V2> subMap(K fromKey, K toKey) {
1501          return transformEntries(
1502              fromMap().subMap(fromKey, toKey), transformer);
1503        }
1504    
1505        public SortedMap<K, V2> tailMap(K fromKey) {
1506          return transformEntries(fromMap().tailMap(fromKey), transformer);
1507        }
1508      }
1509    
1510      /**
1511       * Returns a map containing the mappings in {@code unfiltered} whose keys
1512       * satisfy a predicate. The returned map is a live view of {@code unfiltered};
1513       * changes to one affect the other.
1514       *
1515       * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
1516       * values()} views have iterators that don't support {@code remove()}, but all
1517       * other methods are supported by the map and its views. When given a key that
1518       * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()}
1519       * methods throw an {@link IllegalArgumentException}.
1520       *
1521       * <p>When methods such as {@code removeAll()} and {@code clear()} are called
1522       * on the filtered map or its views, only mappings whose keys satisfy the
1523       * filter will be removed from the underlying map.
1524       *
1525       * <p>The returned map isn't threadsafe or serializable, even if {@code
1526       * unfiltered} is.
1527       *
1528       * <p>Many of the filtered map's methods, such as {@code size()},
1529       * iterate across every key/value mapping in the underlying map and determine
1530       * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1531       * faster to copy the filtered map and use the copy.
1532       *
1533       * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with
1534       * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
1535       * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
1536       * inconsistent with equals.
1537       */
1538      public static <K, V> Map<K, V> filterKeys(
1539          Map<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1540        if (unfiltered instanceof SortedMap) {
1541          return filterKeys((SortedMap<K, V>) unfiltered, keyPredicate);
1542        }
1543        checkNotNull(keyPredicate);
1544        Predicate<Entry<K, V>> entryPredicate =
1545            new Predicate<Entry<K, V>>() {
1546              public boolean apply(Entry<K, V> input) {
1547                return keyPredicate.apply(input.getKey());
1548              }
1549            };
1550        return (unfiltered instanceof AbstractFilteredMap)
1551            ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate)
1552            : new FilteredKeyMap<K, V>(
1553                checkNotNull(unfiltered), keyPredicate, entryPredicate);
1554      }
1555    
1556      /**
1557       * Returns a sorted map containing the mappings in {@code unfiltered} whose
1558       * keys satisfy a predicate. The returned map is a live view of {@code
1559       * unfiltered}; changes to one affect the other.
1560       *
1561       * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
1562       * values()} views have iterators that don't support {@code remove()}, but all
1563       * other methods are supported by the map and its views. When given a key that
1564       * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()}
1565       * methods throw an {@link IllegalArgumentException}.
1566       *
1567       * <p>When methods such as {@code removeAll()} and {@code clear()} are called
1568       * on the filtered map or its views, only mappings whose keys satisfy the
1569       * filter will be removed from the underlying map.
1570       *
1571       * <p>The returned map isn't threadsafe or serializable, even if {@code
1572       * unfiltered} is.
1573       *
1574       * <p>Many of the filtered map's methods, such as {@code size()},
1575       * iterate across every key/value mapping in the underlying map and determine
1576       * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1577       * faster to copy the filtered map and use the copy.
1578       *
1579       * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with
1580       * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
1581       * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
1582       * inconsistent with equals.
1583       *
1584       * @since 11.0
1585       */
1586      public static <K, V> SortedMap<K, V> filterKeys(
1587          SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1588        // TODO: Return a subclass of Maps.FilteredKeyMap for slightly better
1589        // performance.
1590        checkNotNull(keyPredicate);
1591        Predicate<Entry<K, V>> entryPredicate = new Predicate<Entry<K, V>>() {
1592          public boolean apply(Entry<K, V> input) {
1593            return keyPredicate.apply(input.getKey());
1594          }
1595        };
1596        return filterEntries(unfiltered, entryPredicate);
1597      }
1598    
1599      /**
1600       * Returns a map containing the mappings in {@code unfiltered} whose values
1601       * satisfy a predicate. The returned map is a live view of {@code unfiltered};
1602       * changes to one affect the other.
1603       *
1604       * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
1605       * values()} views have iterators that don't support {@code remove()}, but all
1606       * other methods are supported by the map and its views. When given a value
1607       * that doesn't satisfy the predicate, the map's {@code put()}, {@code
1608       * putAll()}, and {@link Entry#setValue} methods throw an {@link
1609       * IllegalArgumentException}.
1610       *
1611       * <p>When methods such as {@code removeAll()} and {@code clear()} are called
1612       * on the filtered map or its views, only mappings whose values satisfy the
1613       * filter will be removed from the underlying map.
1614       *
1615       * <p>The returned map isn't threadsafe or serializable, even if {@code
1616       * unfiltered} is.
1617       *
1618       * <p>Many of the filtered map's methods, such as {@code size()},
1619       * iterate across every key/value mapping in the underlying map and determine
1620       * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1621       * faster to copy the filtered map and use the copy.
1622       *
1623       * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
1624       * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
1625       * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
1626       * inconsistent with equals.
1627       */
1628      public static <K, V> Map<K, V> filterValues(
1629          Map<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
1630        if (unfiltered instanceof SortedMap) {
1631          return filterValues((SortedMap<K, V>) unfiltered, valuePredicate);
1632        }
1633        checkNotNull(valuePredicate);
1634        Predicate<Entry<K, V>> entryPredicate =
1635            new Predicate<Entry<K, V>>() {
1636              public boolean apply(Entry<K, V> input) {
1637                return valuePredicate.apply(input.getValue());
1638              }
1639            };
1640        return filterEntries(unfiltered, entryPredicate);
1641      }
1642    
1643      /**
1644       * Returns a sorted map containing the mappings in {@code unfiltered} whose
1645       * values satisfy a predicate. The returned map is a live view of {@code
1646       * unfiltered}; changes to one affect the other.
1647       *
1648       * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
1649       * values()} views have iterators that don't support {@code remove()}, but all
1650       * other methods are supported by the map and its views. When given a value
1651       * that doesn't satisfy the predicate, the map's {@code put()}, {@code
1652       * putAll()}, and {@link Entry#setValue} methods throw an {@link
1653       * IllegalArgumentException}.
1654       *
1655       * <p>When methods such as {@code removeAll()} and {@code clear()} are called
1656       * on the filtered map or its views, only mappings whose values satisfy the
1657       * filter will be removed from the underlying map.
1658       *
1659       * <p>The returned map isn't threadsafe or serializable, even if {@code
1660       * unfiltered} is.
1661       *
1662       * <p>Many of the filtered map's methods, such as {@code size()},
1663       * iterate across every key/value mapping in the underlying map and determine
1664       * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1665       * faster to copy the filtered map and use the copy.
1666       *
1667       * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
1668       * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
1669       * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
1670       * inconsistent with equals.
1671       *
1672       * @since 11.0
1673       */
1674      public static <K, V> SortedMap<K, V> filterValues(
1675          SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
1676        checkNotNull(valuePredicate);
1677        Predicate<Entry<K, V>> entryPredicate =
1678            new Predicate<Entry<K, V>>() {
1679              public boolean apply(Entry<K, V> input) {
1680                return valuePredicate.apply(input.getValue());
1681              }
1682            };
1683        return filterEntries(unfiltered, entryPredicate);
1684      }
1685    
1686      /**
1687       * Returns a map containing the mappings in {@code unfiltered} that satisfy a
1688       * predicate. The returned map is a live view of {@code unfiltered}; changes
1689       * to one affect the other.
1690       *
1691       * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
1692       * values()} views have iterators that don't support {@code remove()}, but all
1693       * other methods are supported by the map and its views. When given a
1694       * key/value pair that doesn't satisfy the predicate, the map's {@code put()}
1695       * and {@code putAll()} methods throw an {@link IllegalArgumentException}.
1696       * Similarly, the map's entries have a {@link Entry#setValue} method that
1697       * throws an {@link IllegalArgumentException} when the existing key and the
1698       * provided value don't satisfy the predicate.
1699       *
1700       * <p>When methods such as {@code removeAll()} and {@code clear()} are called
1701       * on the filtered map or its views, only mappings that satisfy the filter
1702       * will be removed from the underlying map.
1703       *
1704       * <p>The returned map isn't threadsafe or serializable, even if {@code
1705       * unfiltered} is.
1706       *
1707       * <p>Many of the filtered map's methods, such as {@code size()},
1708       * iterate across every key/value mapping in the underlying map and determine
1709       * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1710       * faster to copy the filtered map and use the copy.
1711       *
1712       * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
1713       * equals</i>, as documented at {@link Predicate#apply}.
1714       */
1715      public static <K, V> Map<K, V> filterEntries(
1716          Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
1717        if (unfiltered instanceof SortedMap) {
1718          return filterEntries((SortedMap<K, V>) unfiltered, entryPredicate);
1719        }
1720        checkNotNull(entryPredicate);
1721        return (unfiltered instanceof AbstractFilteredMap)
1722            ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate)
1723            : new FilteredEntryMap<K, V>(checkNotNull(unfiltered), entryPredicate);
1724      }
1725    
1726      /**
1727       * Returns a sorted map containing the mappings in {@code unfiltered} that
1728       * satisfy a predicate. The returned map is a live view of {@code unfiltered};
1729       * changes to one affect the other.
1730       *
1731       * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
1732       * values()} views have iterators that don't support {@code remove()}, but all
1733       * other methods are supported by the map and its views. When given a
1734       * key/value pair that doesn't satisfy the predicate, the map's {@code put()}
1735       * and {@code putAll()} methods throw an {@link IllegalArgumentException}.
1736       * Similarly, the map's entries have a {@link Entry#setValue} method that
1737       * throws an {@link IllegalArgumentException} when the existing key and the
1738       * provided value don't satisfy the predicate.
1739       *
1740       * <p>When methods such as {@code removeAll()} and {@code clear()} are called
1741       * on the filtered map or its views, only mappings that satisfy the filter
1742       * will be removed from the underlying map.
1743       *
1744       * <p>The returned map isn't threadsafe or serializable, even if {@code
1745       * unfiltered} is.
1746       *
1747       * <p>Many of the filtered map's methods, such as {@code size()},
1748       * iterate across every key/value mapping in the underlying map and determine
1749       * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1750       * faster to copy the filtered map and use the copy.
1751       *
1752       * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
1753       * equals</i>, as documented at {@link Predicate#apply}.
1754       *
1755       * @since 11.0
1756       */
1757      public static <K, V> SortedMap<K, V> filterEntries(
1758          SortedMap<K, V> unfiltered,
1759          Predicate<? super Entry<K, V>> entryPredicate) {
1760        checkNotNull(entryPredicate);
1761        return (unfiltered instanceof FilteredEntrySortedMap)
1762            ? filterFiltered((FilteredEntrySortedMap<K, V>) unfiltered, entryPredicate)
1763            : new FilteredEntrySortedMap<K, V>(checkNotNull(unfiltered), entryPredicate);
1764      }
1765    
1766      /**
1767       * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
1768       * filtering a filtered map.
1769       */
1770      private static <K, V> Map<K, V> filterFiltered(AbstractFilteredMap<K, V> map,
1771          Predicate<? super Entry<K, V>> entryPredicate) {
1772        Predicate<Entry<K, V>> predicate =
1773            Predicates.and(map.predicate, entryPredicate);
1774        return new FilteredEntryMap<K, V>(map.unfiltered, predicate);
1775      }
1776    
1777      private abstract static class AbstractFilteredMap<K, V>
1778          extends AbstractMap<K, V> {
1779        final Map<K, V> unfiltered;
1780        final Predicate<? super Entry<K, V>> predicate;
1781    
1782        AbstractFilteredMap(
1783            Map<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
1784          this.unfiltered = unfiltered;
1785          this.predicate = predicate;
1786        }
1787    
1788        boolean apply(Object key, V value) {
1789          // This method is called only when the key is in the map, implying that
1790          // key is a K.
1791          @SuppressWarnings("unchecked")
1792          K k = (K) key;
1793          return predicate.apply(Maps.immutableEntry(k, value));
1794        }
1795    
1796        @Override
1797        public V put(K key, V value) {
1798          checkArgument(apply(key, value));
1799          return unfiltered.put(key, value);
1800        }
1801    
1802        @Override
1803        public void putAll(Map<? extends K, ? extends V> map) {
1804          for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
1805            checkArgument(apply(entry.getKey(), entry.getValue()));
1806          }
1807          unfiltered.putAll(map);
1808        }
1809    
1810        @Override
1811        public boolean containsKey(Object key) {
1812          return unfiltered.containsKey(key) && apply(key, unfiltered.get(key));
1813        }
1814    
1815        @Override
1816        public V get(Object key) {
1817          V value = unfiltered.get(key);
1818          return ((value != null) && apply(key, value)) ? value : null;
1819        }
1820    
1821        @Override
1822        public boolean isEmpty() {
1823          return entrySet().isEmpty();
1824        }
1825    
1826        @Override
1827        public V remove(Object key) {
1828          return containsKey(key) ? unfiltered.remove(key) : null;
1829        }
1830    
1831        Collection<V> values;
1832    
1833        @Override
1834        public Collection<V> values() {
1835          Collection<V> result = values;
1836          return (result == null) ? values = new Values() : result;
1837        }
1838    
1839        class Values extends AbstractCollection<V> {
1840          @Override
1841          public Iterator<V> iterator() {
1842            final Iterator<Entry<K, V>> entryIterator = entrySet().iterator();
1843            return new UnmodifiableIterator<V>() {
1844              public boolean hasNext() {
1845                return entryIterator.hasNext();
1846              }
1847    
1848              public V next() {
1849                return entryIterator.next().getValue();
1850              }
1851            };
1852          }
1853    
1854          @Override
1855          public int size() {
1856            return entrySet().size();
1857          }
1858    
1859          @Override
1860          public void clear() {
1861            entrySet().clear();
1862          }
1863    
1864          @Override
1865          public boolean isEmpty() {
1866            return entrySet().isEmpty();
1867          }
1868    
1869          @Override
1870          public boolean remove(Object o) {
1871            Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator();
1872            while (iterator.hasNext()) {
1873              Entry<K, V> entry = iterator.next();
1874              if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) {
1875                iterator.remove();
1876                return true;
1877              }
1878            }
1879            return false;
1880          }
1881    
1882          @Override
1883          public boolean removeAll(Collection<?> collection) {
1884            checkNotNull(collection);
1885            boolean changed = false;
1886            Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator();
1887            while (iterator.hasNext()) {
1888              Entry<K, V> entry = iterator.next();
1889              if (collection.contains(entry.getValue()) && predicate.apply(entry)) {
1890                iterator.remove();
1891                changed = true;
1892              }
1893            }
1894            return changed;
1895          }
1896    
1897          @Override
1898          public boolean retainAll(Collection<?> collection) {
1899            checkNotNull(collection);
1900            boolean changed = false;
1901            Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator();
1902            while (iterator.hasNext()) {
1903              Entry<K, V> entry = iterator.next();
1904              if (!collection.contains(entry.getValue())
1905                  && predicate.apply(entry)) {
1906                iterator.remove();
1907                changed = true;
1908              }
1909            }
1910            return changed;
1911          }
1912    
1913          @Override
1914          public Object[] toArray() {
1915            // creating an ArrayList so filtering happens once
1916            return Lists.newArrayList(iterator()).toArray();
1917          }
1918    
1919          @Override
1920          public <T> T[] toArray(T[] array) {
1921            return Lists.newArrayList(iterator()).toArray(array);
1922          }
1923        }
1924      }
1925      /**
1926       * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
1927       * filtering a filtered sorted map.
1928       */
1929      private static <K, V> SortedMap<K, V> filterFiltered(
1930          FilteredEntrySortedMap<K, V> map,
1931          Predicate<? super Entry<K, V>> entryPredicate) {
1932        Predicate<Entry<K, V>> predicate
1933            = Predicates.and(map.predicate, entryPredicate);
1934        return new FilteredEntrySortedMap<K, V>(map.sortedMap(), predicate);
1935      }
1936    
1937      private static class FilteredEntrySortedMap<K, V>
1938          extends FilteredEntryMap<K, V> implements SortedMap<K, V> {
1939    
1940        FilteredEntrySortedMap(SortedMap<K, V> unfiltered,
1941            Predicate<? super Entry<K, V>> entryPredicate) {
1942          super(unfiltered, entryPredicate);
1943        }
1944    
1945        SortedMap<K, V> sortedMap() {
1946          return (SortedMap<K, V>) unfiltered;
1947        }
1948    
1949        public Comparator<? super K> comparator() {
1950          return sortedMap().comparator();
1951        }
1952    
1953        public K firstKey() {
1954          // correctly throws NoSuchElementException when filtered map is empty.
1955          return keySet().iterator().next();
1956        }
1957    
1958        public K lastKey() {
1959          SortedMap<K, V> headMap = sortedMap();
1960          while (true) {
1961            // correctly throws NoSuchElementException when filtered map is empty.
1962            K key = headMap.lastKey();
1963            if (apply(key, unfiltered.get(key))) {
1964              return key;
1965            }
1966            headMap = sortedMap().headMap(key);
1967          }
1968        }
1969    
1970        public SortedMap<K, V> headMap(K toKey) {
1971          return new FilteredEntrySortedMap<K, V>(sortedMap().headMap(toKey), predicate);
1972        }
1973    
1974        public SortedMap<K, V> subMap(K fromKey, K toKey) {
1975          return new FilteredEntrySortedMap<K, V>(
1976              sortedMap().subMap(fromKey, toKey), predicate);
1977        }
1978    
1979        public SortedMap<K, V> tailMap(K fromKey) {
1980          return new FilteredEntrySortedMap<K, V>(
1981              sortedMap().tailMap(fromKey), predicate);
1982        }
1983      }
1984    
1985      private static class FilteredKeyMap<K, V> extends AbstractFilteredMap<K, V> {
1986        Predicate<? super K> keyPredicate;
1987    
1988        FilteredKeyMap(Map<K, V> unfiltered, Predicate<? super K> keyPredicate,
1989            Predicate<Entry<K, V>> entryPredicate) {
1990          super(unfiltered, entryPredicate);
1991          this.keyPredicate = keyPredicate;
1992        }
1993    
1994        Set<Entry<K, V>> entrySet;
1995    
1996        @Override
1997        public Set<Entry<K, V>> entrySet() {
1998          Set<Entry<K, V>> result = entrySet;
1999          return (result == null)
2000              ? entrySet = Sets.filter(unfiltered.entrySet(), predicate)
2001              : result;
2002        }
2003    
2004        Set<K> keySet;
2005    
2006        @Override
2007        public Set<K> keySet() {
2008          Set<K> result = keySet;
2009          return (result == null)
2010              ? keySet = Sets.filter(unfiltered.keySet(), keyPredicate)
2011              : result;
2012        }
2013    
2014        // The cast is called only when the key is in the unfiltered map, implying
2015        // that key is a K.
2016        @Override
2017        @SuppressWarnings("unchecked")
2018        public boolean containsKey(Object key) {
2019          return unfiltered.containsKey(key) && keyPredicate.apply((K) key);
2020        }
2021      }
2022    
2023      static class FilteredEntryMap<K, V> extends AbstractFilteredMap<K, V> {
2024        /**
2025         * Entries in this set satisfy the predicate, but they don't validate the
2026         * input to {@code Entry.setValue()}.
2027         */
2028        final Set<Entry<K, V>> filteredEntrySet;
2029    
2030        FilteredEntryMap(
2031            Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2032          super(unfiltered, entryPredicate);
2033          filteredEntrySet = Sets.filter(unfiltered.entrySet(), predicate);
2034        }
2035    
2036        Set<Entry<K, V>> entrySet;
2037    
2038        @Override
2039        public Set<Entry<K, V>> entrySet() {
2040          Set<Entry<K, V>> result = entrySet;
2041          return (result == null) ? entrySet = new EntrySet() : result;
2042        }
2043    
2044        private class EntrySet extends ForwardingSet<Entry<K, V>> {
2045          @Override
2046          protected Set<Entry<K, V>> delegate() {
2047            return filteredEntrySet;
2048          }
2049    
2050          @Override
2051          public Iterator<Entry<K, V>> iterator() {
2052            final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator();
2053            return new UnmodifiableIterator<Entry<K, V>>() {
2054              public boolean hasNext() {
2055                return iterator.hasNext();
2056              }
2057    
2058              public Entry<K, V> next() {
2059                final Entry<K, V> entry = iterator.next();
2060                return new ForwardingMapEntry<K, V>() {
2061                  @Override
2062                  protected Entry<K, V> delegate() {
2063                    return entry;
2064                  }
2065    
2066                  @Override
2067                  public V setValue(V value) {
2068                    checkArgument(apply(entry.getKey(), value));
2069                    return super.setValue(value);
2070                  }
2071                };
2072              }
2073            };
2074          }
2075        }
2076    
2077        Set<K> keySet;
2078    
2079        @Override
2080        public Set<K> keySet() {
2081          Set<K> result = keySet;
2082          return (result == null) ? keySet = new KeySet() : result;
2083        }
2084    
2085        private class KeySet extends Sets.ImprovedAbstractSet<K> {
2086          @Override
2087          public Iterator<K> iterator() {
2088            final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator();
2089            return new UnmodifiableIterator<K>() {
2090              public boolean hasNext() {
2091                return iterator.hasNext();
2092              }
2093    
2094              public K next() {
2095                return iterator.next().getKey();
2096              }
2097            };
2098          }
2099    
2100          @Override
2101          public int size() {
2102            return filteredEntrySet.size();
2103          }
2104    
2105          @Override
2106          public void clear() {
2107            filteredEntrySet.clear();
2108          }
2109    
2110          @Override
2111          public boolean contains(Object o) {
2112            return containsKey(o);
2113          }
2114    
2115          @Override
2116          public boolean remove(Object o) {
2117            if (containsKey(o)) {
2118              unfiltered.remove(o);
2119              return true;
2120            }
2121            return false;
2122          }
2123    
2124          @Override
2125          public boolean retainAll(Collection<?> collection) {
2126            checkNotNull(collection); // for GWT
2127            boolean changed = false;
2128            Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator();
2129            while (iterator.hasNext()) {
2130              Entry<K, V> entry = iterator.next();
2131              if (predicate.apply(entry) && !collection.contains(entry.getKey())) {
2132                iterator.remove();
2133                changed = true;
2134              }
2135            }
2136            return changed;
2137          }
2138    
2139          @Override
2140          public Object[] toArray() {
2141            // creating an ArrayList so filtering happens once
2142            return Lists.newArrayList(iterator()).toArray();
2143          }
2144    
2145          @Override
2146          public <T> T[] toArray(T[] array) {
2147            return Lists.newArrayList(iterator()).toArray(array);
2148          }
2149        }
2150      }
2151    
2152      @Nullable private static <K, V> Entry<K, V> unmodifiableOrNull(@Nullable Entry<K, V> entry) {
2153        return (entry == null) ? null : Maps.unmodifiableEntry(entry);
2154      }
2155    
2156      /**
2157       * {@code AbstractMap} extension that implements {@link #isEmpty()} as {@code
2158       * entrySet().isEmpty()} instead of {@code size() == 0} to speed up
2159       * implementations where {@code size()} is O(n), and it delegates the {@code
2160       * isEmpty()} methods of its key set and value collection to this
2161       * implementation.
2162       */
2163      @GwtCompatible
2164      abstract static class ImprovedAbstractMap<K, V> extends AbstractMap<K, V> {
2165        /**
2166         * Creates the entry set to be returned by {@link #entrySet()}. This method
2167         * is invoked at most once on a given map, at the time when {@code entrySet}
2168         * is first called.
2169         */
2170        protected abstract Set<Entry<K, V>> createEntrySet();
2171    
2172        private Set<Entry<K, V>> entrySet;
2173    
2174        @Override
2175        public Set<Entry<K, V>> entrySet() {
2176          Set<Entry<K, V>> result = entrySet;
2177          if (result == null) {
2178            entrySet = result = createEntrySet();
2179          }
2180          return result;
2181        }
2182    
2183        private Set<K> keySet;
2184    
2185        @Override
2186        public Set<K> keySet() {
2187          Set<K> result = keySet;
2188          if (result == null) {
2189            return keySet = new KeySet<K, V>() {
2190              @Override
2191              Map<K, V> map() {
2192                return ImprovedAbstractMap.this;
2193              }
2194            };
2195          }
2196          return result;
2197        }
2198    
2199        private Collection<V> values;
2200    
2201        @Override
2202        public Collection<V> values() {
2203          Collection<V> result = values;
2204          if (result == null) {
2205            return values = new Values<K, V>() {
2206              @Override
2207              Map<K, V> map() {
2208                return ImprovedAbstractMap.this;
2209              }
2210            };
2211          }
2212          return result;
2213        }
2214      }
2215    
2216      static final MapJoiner STANDARD_JOINER =
2217          Collections2.STANDARD_JOINER.withKeyValueSeparator("=");
2218    
2219      /**
2220       * Delegates to {@link Map#get}. Returns {@code null} on {@code
2221       * ClassCastException}.
2222       */
2223      static <V> V safeGet(Map<?, V> map, Object key) {
2224        try {
2225          return map.get(key);
2226        } catch (ClassCastException e) {
2227          return null;
2228        }
2229      }
2230    
2231      /**
2232       * Delegates to {@link Map#containsKey}. Returns {@code false} on {@code
2233       * ClassCastException}
2234       */
2235      static boolean safeContainsKey(Map<?, ?> map, Object key) {
2236        try {
2237          return map.containsKey(key);
2238        } catch (ClassCastException e) {
2239          return false;
2240        }
2241      }
2242    
2243      /**
2244       * Implements {@code Collection.contains} safely for forwarding collections of
2245       * map entries. If {@code o} is an instance of {@code Map.Entry}, it is
2246       * wrapped using {@link #unmodifiableEntry} to protect against a possible
2247       * nefarious equals method.
2248       *
2249       * <p>Note that {@code c} is the backing (delegate) collection, rather than
2250       * the forwarding collection.
2251       *
2252       * @param c the delegate (unwrapped) collection of map entries
2253       * @param o the object that might be contained in {@code c}
2254       * @return {@code true} if {@code c} contains {@code o}
2255       */
2256      static <K, V> boolean containsEntryImpl(Collection<Entry<K, V>> c, Object o) {
2257        if (!(o instanceof Entry)) {
2258          return false;
2259        }
2260        return c.contains(unmodifiableEntry((Entry<?, ?>) o));
2261      }
2262    
2263      /**
2264       * Implements {@code Collection.remove} safely for forwarding collections of
2265       * map entries. If {@code o} is an instance of {@code Map.Entry}, it is
2266       * wrapped using {@link #unmodifiableEntry} to protect against a possible
2267       * nefarious equals method.
2268       *
2269       * <p>Note that {@code c} is backing (delegate) collection, rather than the
2270       * forwarding collection.
2271       *
2272       * @param c the delegate (unwrapped) collection of map entries
2273       * @param o the object to remove from {@code c}
2274       * @return {@code true} if {@code c} was changed
2275       */
2276      static <K, V> boolean removeEntryImpl(Collection<Entry<K, V>> c, Object o) {
2277        if (!(o instanceof Entry)) {
2278          return false;
2279        }
2280        return c.remove(unmodifiableEntry((Entry<?, ?>) o));
2281      }
2282    
2283      /**
2284       * An implementation of {@link Map#equals}.
2285       */
2286      static boolean equalsImpl(Map<?, ?> map, Object object) {
2287        if (map == object) {
2288          return true;
2289        }
2290        if (object instanceof Map) {
2291          Map<?, ?> o = (Map<?, ?>) object;
2292          return map.entrySet().equals(o.entrySet());
2293        }
2294        return false;
2295      }
2296    
2297      /**
2298       * An implementation of {@link Map#hashCode}.
2299       */
2300      static int hashCodeImpl(Map<?, ?> map) {
2301        return Sets.hashCodeImpl(map.entrySet());
2302      }
2303    
2304      /**
2305       * An implementation of {@link Map#toString}.
2306       */
2307      static String toStringImpl(Map<?, ?> map) {
2308        StringBuilder sb
2309            = Collections2.newStringBuilderForCollection(map.size()).append('{');
2310        STANDARD_JOINER.appendTo(sb, map);
2311        return sb.append('}').toString();
2312      }
2313    
2314      /**
2315       * An implementation of {@link Map#putAll}.
2316       */
2317      static <K, V> void putAllImpl(
2318          Map<K, V> self, Map<? extends K, ? extends V> map) {
2319        for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
2320          self.put(entry.getKey(), entry.getValue());
2321        }
2322      }
2323    
2324      /**
2325       * An admittedly inefficient implementation of {@link Map#containsKey}.
2326       */
2327      static boolean containsKeyImpl(Map<?, ?> map, @Nullable Object key) {
2328        for (Entry<?, ?> entry : map.entrySet()) {
2329          if (Objects.equal(entry.getKey(), key)) {
2330            return true;
2331          }
2332        }
2333        return false;
2334      }
2335    
2336      /**
2337       * An implementation of {@link Map#containsValue}.
2338       */
2339      static boolean containsValueImpl(Map<?, ?> map, @Nullable Object value) {
2340        for (Entry<?, ?> entry : map.entrySet()) {
2341          if (Objects.equal(entry.getValue(), value)) {
2342            return true;
2343          }
2344        }
2345        return false;
2346      }
2347    
2348      static <K, V> Iterator<K> keyIterator(Iterator<Entry<K, V>> entryIterator) {
2349        return new TransformedIterator<Entry<K, V>, K>(entryIterator) {
2350          @Override
2351          K transform(Entry<K, V> entry) {
2352            return entry.getKey();
2353          }
2354        };
2355      }
2356    
2357      abstract static class KeySet<K, V> extends Sets.ImprovedAbstractSet<K> {
2358        abstract Map<K, V> map();
2359    
2360        @Override
2361        public Iterator<K> iterator() {
2362          return keyIterator(map().entrySet().iterator());
2363        }
2364    
2365        @Override
2366        public int size() {
2367          return map().size();
2368        }
2369    
2370        @Override
2371        public boolean isEmpty() {
2372          return map().isEmpty();
2373        }
2374    
2375        @Override
2376        public boolean contains(Object o) {
2377          return map().containsKey(o);
2378        }
2379    
2380        @Override
2381        public boolean remove(Object o) {
2382          if (contains(o)) {
2383            map().remove(o);
2384            return true;
2385          }
2386          return false;
2387        }
2388    
2389        @Override
2390        public void clear() {
2391          map().clear();
2392        }
2393      }
2394    
2395      @Nullable
2396      static <K> K keyOrNull(@Nullable Entry<K, ?> entry) {
2397        return (entry == null) ? null : entry.getKey();
2398      }
2399    
2400      static <K, V> Iterator<V> valueIterator(Iterator<Entry<K, V>> entryIterator) {
2401        return new TransformedIterator<Entry<K, V>, V>(entryIterator) {
2402          @Override
2403          V transform(Entry<K, V> entry) {
2404            return entry.getValue();
2405          }
2406        };
2407      }
2408    
2409      static <K, V> UnmodifiableIterator<V> valueIterator(
2410          final UnmodifiableIterator<Entry<K, V>> entryIterator) {
2411        return new UnmodifiableIterator<V>() {
2412          public boolean hasNext() {
2413            return entryIterator.hasNext();
2414          }
2415    
2416          public V next() {
2417            return entryIterator.next().getValue();
2418          }
2419        };
2420      }
2421    
2422      abstract static class Values<K, V> extends AbstractCollection<V> {
2423        abstract Map<K, V> map();
2424    
2425        @Override
2426        public Iterator<V> iterator() {
2427          return valueIterator(map().entrySet().iterator());
2428        }
2429    
2430        @Override
2431        public boolean remove(Object o) {
2432          try {
2433            return super.remove(o);
2434          } catch (UnsupportedOperationException e) {
2435            for (Entry<K, V> entry : map().entrySet()) {
2436              if (Objects.equal(o, entry.getValue())) {
2437                map().remove(entry.getKey());
2438                return true;
2439              }
2440            }
2441            return false;
2442          }
2443        }
2444    
2445        @Override
2446        public boolean removeAll(Collection<?> c) {
2447          try {
2448            return super.removeAll(checkNotNull(c));
2449          } catch (UnsupportedOperationException e) {
2450            Set<K> toRemove = Sets.newHashSet();
2451            for (Entry<K, V> entry : map().entrySet()) {
2452              if (c.contains(entry.getValue())) {
2453                toRemove.add(entry.getKey());
2454              }
2455            }
2456            return map().keySet().removeAll(toRemove);
2457          }
2458        }
2459    
2460        @Override
2461        public boolean retainAll(Collection<?> c) {
2462          try {
2463            return super.retainAll(checkNotNull(c));
2464          } catch (UnsupportedOperationException e) {
2465            Set<K> toRetain = Sets.newHashSet();
2466            for (Entry<K, V> entry : map().entrySet()) {
2467              if (c.contains(entry.getValue())) {
2468                toRetain.add(entry.getKey());
2469              }
2470            }
2471            return map().keySet().retainAll(toRetain);
2472          }
2473        }
2474    
2475        @Override
2476        public int size() {
2477          return map().size();
2478        }
2479    
2480        @Override
2481        public boolean isEmpty() {
2482          return map().isEmpty();
2483        }
2484    
2485        @Override
2486        public boolean contains(@Nullable Object o) {
2487          return map().containsValue(o);
2488        }
2489    
2490        @Override
2491        public void clear() {
2492          map().clear();
2493        }
2494      }
2495    
2496      abstract static class EntrySet<K, V>
2497          extends Sets.ImprovedAbstractSet<Entry<K, V>> {
2498        abstract Map<K, V> map();
2499    
2500        @Override
2501        public int size() {
2502          return map().size();
2503        }
2504    
2505        @Override
2506        public void clear() {
2507          map().clear();
2508        }
2509    
2510        @Override
2511        public boolean contains(Object o) {
2512          if (o instanceof Entry) {
2513            Entry<?, ?> entry = (Entry<?, ?>) o;
2514            Object key = entry.getKey();
2515            V value = map().get(key);
2516            return Objects.equal(value, entry.getValue())
2517                && (value != null || map().containsKey(key));
2518          }
2519          return false;
2520        }
2521    
2522        @Override
2523        public boolean isEmpty() {
2524          return map().isEmpty();
2525        }
2526    
2527        @Override
2528        public boolean remove(Object o) {
2529          if (contains(o)) {
2530            Entry<?, ?> entry = (Entry<?, ?>) o;
2531            return map().keySet().remove(entry.getKey());
2532          }
2533          return false;
2534        }
2535    
2536        @Override
2537        public boolean removeAll(Collection<?> c) {
2538          try {
2539            return super.removeAll(checkNotNull(c));
2540          } catch (UnsupportedOperationException e) {
2541            // if the iterators don't support remove
2542            boolean changed = true;
2543            for (Object o : c) {
2544              changed |= remove(o);
2545            }
2546            return changed;
2547          }
2548        }
2549    
2550        @Override
2551        public boolean retainAll(Collection<?> c) {
2552          try {
2553            return super.retainAll(checkNotNull(c));
2554          } catch (UnsupportedOperationException e) {
2555            // if the iterators don't support remove
2556            Set<Object> keys = Sets.newHashSetWithExpectedSize(c.size());
2557            for (Object o : c) {
2558              if (contains(o)) {
2559                Entry<?, ?> entry = (Entry<?, ?>) o;
2560                keys.add(entry.getKey());
2561              }
2562            }
2563            return map().keySet().retainAll(keys);
2564          }
2565        }
2566      }
2567    }