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