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