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