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