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