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