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