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