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