001 /* 002 * Copyright (C) 2007 Google Inc. 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 017 package com.google.common.collect; 018 019 import static com.google.common.base.Preconditions.checkArgument; 020 import static com.google.common.base.Preconditions.checkNotNull; 021 022 import com.google.common.annotations.Beta; 023 import com.google.common.annotations.GwtCompatible; 024 import com.google.common.annotations.GwtIncompatible; 025 import com.google.common.base.Function; 026 import com.google.common.base.Joiner.MapJoiner; 027 import com.google.common.base.Objects; 028 import com.google.common.base.Predicate; 029 import com.google.common.base.Predicates; 030 import com.google.common.base.Supplier; 031 import com.google.common.collect.MapDifference.ValueDifference; 032 import com.google.common.primitives.Ints; 033 034 import java.io.Serializable; 035 import java.util.AbstractCollection; 036 import java.util.AbstractMap; 037 import java.util.AbstractSet; 038 import java.util.Collection; 039 import java.util.Collections; 040 import java.util.Comparator; 041 import java.util.EnumMap; 042 import java.util.Enumeration; 043 import java.util.HashMap; 044 import java.util.IdentityHashMap; 045 import java.util.Iterator; 046 import java.util.LinkedHashMap; 047 import java.util.Map; 048 import java.util.Map.Entry; 049 import java.util.Properties; 050 import java.util.Set; 051 import java.util.SortedMap; 052 import java.util.TreeMap; 053 import java.util.concurrent.ConcurrentMap; 054 055 import javax.annotation.Nullable; 056 057 /** 058 * Static utility methods pertaining to {@link Map} instances. Also see this 059 * class's counterparts {@link Lists} and {@link Sets}. 060 * 061 * @author Kevin Bourrillion 062 * @author Mike Bostock 063 * @author Isaac Shum 064 * @author Louis Wasserman 065 * @since 2 (imported from Google Collections Library) 066 */ 067 @GwtCompatible(emulated = true) 068 public final class Maps { 069 private Maps() {} 070 071 /** 072 * Creates a <i>mutable</i>, empty {@code HashMap} instance. 073 * 074 * <p><b>Note:</b> if mutability is not required, use {@link 075 * ImmutableMap#of()} instead. 076 * 077 * <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link 078 * #newEnumMap} instead. 079 * 080 * @return a new, empty {@code HashMap} 081 */ 082 public static <K, V> HashMap<K, V> newHashMap() { 083 return new HashMap<K, V>(); 084 } 085 086 /** 087 * Creates a {@code HashMap} instance with enough capacity to hold the 088 * specified number of elements without rehashing. 089 * 090 * @param expectedSize the expected size 091 * @return a new, empty {@code HashMap} with enough capacity to hold {@code 092 * expectedSize} elements without rehashing 093 * @throws IllegalArgumentException if {@code expectedSize} is negative 094 */ 095 public static <K, V> HashMap<K, V> newHashMapWithExpectedSize( 096 int expectedSize) { 097 /* 098 * The HashMap is constructed with an initialCapacity that's greater than 099 * expectedSize. The larger value is necessary because HashMap resizes its 100 * internal array if the map size exceeds loadFactor * initialCapacity. 101 */ 102 return new HashMap<K, V>(capacity(expectedSize)); 103 } 104 105 /** 106 * Returns an appropriate value for the "capacity" (in reality, "minimum table 107 * size") parameter of a {@link HashMap} constructor, such that the resulting 108 * table will be between 25% and 50% full when it contains {@code 109 * expectedSize} entries, unless {@code expectedSize} is greater than 110 * {@link Integer#MAX_VALUE} / 2. 111 * 112 * @throws IllegalArgumentException if {@code expectedSize} is negative 113 */ 114 static int capacity(int expectedSize) { 115 checkArgument(expectedSize >= 0); 116 // Avoid the int overflow if expectedSize > (Integer.MAX_VALUE / 2) 117 return Ints.saturatedCast(Math.max(expectedSize * 2L, 16L)); 118 } 119 120 /** 121 * Creates a <i>mutable</i> {@code HashMap} instance with the same mappings as 122 * the specified map. 123 * 124 * <p><b>Note:</b> if mutability is not required, use {@link 125 * ImmutableMap#copyOf(Map)} instead. 126 * 127 * <p><b>Note:</b> if {@code K} is an {@link Enum} type, use {@link 128 * #newEnumMap} instead. 129 * 130 * @param map the mappings to be placed in the new map 131 * @return a new {@code HashMap} initialized with the mappings from {@code 132 * map} 133 */ 134 public static <K, V> HashMap<K, V> newHashMap( 135 Map<? extends K, ? extends V> map) { 136 return new HashMap<K, V>(map); 137 } 138 139 /** 140 * Creates a <i>mutable</i>, empty, insertion-ordered {@code LinkedHashMap} 141 * instance. 142 * 143 * <p><b>Note:</b> if mutability is not required, use {@link 144 * ImmutableMap#of()} instead. 145 * 146 * @return a new, empty {@code LinkedHashMap} 147 */ 148 public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() { 149 return new LinkedHashMap<K, V>(); 150 } 151 152 /** 153 * Creates a <i>mutable</i>, insertion-ordered {@code LinkedHashMap} instance 154 * with the same mappings as the specified map. 155 * 156 * <p><b>Note:</b> if mutability is not required, use {@link 157 * ImmutableMap#copyOf(Map)} instead. 158 * 159 * @param map the mappings to be placed in the new map 160 * @return a new, {@code LinkedHashMap} initialized with the mappings from 161 * {@code map} 162 */ 163 public static <K, V> LinkedHashMap<K, V> newLinkedHashMap( 164 Map<? extends K, ? extends V> map) { 165 return new LinkedHashMap<K, V>(map); 166 } 167 168 /** 169 * Returns a general-purpose instance of {@code ConcurrentMap}, which supports 170 * all optional operations of the ConcurrentMap interface. It does not permit 171 * null keys or values. It is serializable. 172 * 173 * <p>This is currently accomplished by calling {@link MapMaker#makeMap()}. 174 * 175 * <p>It is preferable to use {@code MapMaker} directly (rather than through 176 * this method), as it presents numerous useful configuration options, 177 * such as the concurrency level, load factor, key/value reference types, 178 * and value computation. 179 * 180 * @return a new, empty {@code ConcurrentMap} 181 * @since 3 182 */ 183 public static <K, V> ConcurrentMap<K, V> newConcurrentMap() { 184 return new MapMaker().<K, V>makeMap(); 185 } 186 187 /** 188 * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the natural 189 * ordering of its elements. 190 * 191 * <p><b>Note:</b> if mutability is not required, use {@link 192 * ImmutableSortedMap#of()} instead. 193 * 194 * @return a new, empty {@code TreeMap} 195 */ 196 @SuppressWarnings("unchecked") // eclipse doesn't like the raw Comparable 197 public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() { 198 return new TreeMap<K, V>(); 199 } 200 201 /** 202 * Creates a <i>mutable</i> {@code TreeMap} instance with the same mappings as 203 * the specified map and using the same ordering as the specified map. 204 * 205 * <p><b>Note:</b> if mutability is not required, use {@link 206 * ImmutableSortedMap#copyOfSorted(SortedMap)} instead. 207 * 208 * @param map the sorted map whose mappings are to be placed in the new map 209 * and whose comparator is to be used to sort the new map 210 * @return a new {@code TreeMap} initialized with the mappings from {@code 211 * map} and using the comparator of {@code map} 212 */ 213 public static <K, V> TreeMap<K, V> newTreeMap(SortedMap<K, ? extends V> map) { 214 return new TreeMap<K, V>(map); 215 } 216 217 /** 218 * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the given 219 * comparator. 220 * 221 * <p><b>Note:</b> if mutability is not required, use {@code 222 * ImmutableSortedMap.orderedBy(comparator).build()} instead. 223 * 224 * @param comparator the comparator to sort the keys with 225 * @return a new, empty {@code TreeMap} 226 */ 227 public static <C, K extends C, V> TreeMap<K, V> newTreeMap( 228 @Nullable Comparator<C> comparator) { 229 // Ideally, the extra type parameter "C" shouldn't be necessary. It is a 230 // work-around of a compiler type inference quirk that prevents the 231 // following code from being compiled: 232 // Comparator<Class<?>> comparator = null; 233 // Map<Class<? extends Throwable>, String> map = newTreeMap(comparator); 234 return new TreeMap<K, V>(comparator); 235 } 236 237 /** 238 * Creates an {@code EnumMap} instance. 239 * 240 * @param type the key type for this map 241 * @return a new, empty {@code EnumMap} 242 */ 243 public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Class<K> type) { 244 return new EnumMap<K, V>(checkNotNull(type)); 245 } 246 247 /** 248 * Creates an {@code EnumMap} with the same mappings as the specified map. 249 * 250 * @param map the map from which to initialize this {@code EnumMap} 251 * @return a new {@code EnumMap} initialized with the mappings from {@code 252 * map} 253 * @throws IllegalArgumentException if {@code m} is not an {@code EnumMap} 254 * instance and contains no mappings 255 */ 256 public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap( 257 Map<K, ? extends V> map) { 258 return new EnumMap<K, V>(map); 259 } 260 261 /** 262 * Creates an {@code IdentityHashMap} instance. 263 * 264 * @return a new, empty {@code IdentityHashMap} 265 */ 266 public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() { 267 return new IdentityHashMap<K, V>(); 268 } 269 270 /** 271 * Returns a synchronized (thread-safe) bimap backed by the specified bimap. 272 * In order to guarantee serial access, it is critical that <b>all</b> access 273 * to the backing bimap is accomplished through the returned bimap. 274 * 275 * <p>It is imperative that the user manually synchronize on the returned map 276 * when accessing any of its collection views: <pre> {@code 277 * 278 * BiMap<Long, String> map = Maps.synchronizedBiMap( 279 * HashBiMap.<Long, String>create()); 280 * ... 281 * Set<Long> set = map.keySet(); // Needn't be in synchronized block 282 * ... 283 * synchronized (map) { // Synchronizing on map, not set! 284 * Iterator<Long> it = set.iterator(); // Must be in synchronized block 285 * while (it.hasNext()) { 286 * foo(it.next()); 287 * } 288 * }}</pre> 289 * 290 * Failure to follow this advice may result in non-deterministic behavior. 291 * 292 * <p>The returned bimap will be serializable if the specified bimap is 293 * serializable. 294 * 295 * @param bimap the bimap to be wrapped in a synchronized view 296 * @return a sychronized view of the specified bimap 297 */ 298 public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) { 299 return Synchronized.biMap(bimap, null); 300 } 301 302 /** 303 * Computes the difference between two maps. This difference is an immutable 304 * snapshot of the state of the maps at the time this method is called. It 305 * will never change, even if the maps change at a later time. 306 * 307 * <p>Since this method uses {@code HashMap} instances internally, the keys of 308 * the supplied maps must be well-behaved with respect to 309 * {@link Object#equals} and {@link Object#hashCode}. 310 * 311 * <p><b>Note:</b>If you only need to know whether two maps have the same 312 * mappings, call {@code left.equals(right)} instead of this method. 313 * 314 * @param left the map to treat as the "left" map for purposes of comparison 315 * @param right the map to treat as the "right" map for purposes of comparison 316 * @return the difference between the two maps 317 */ 318 public static <K, V> MapDifference<K, V> difference( 319 Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right) { 320 Map<K, V> onlyOnLeft = newHashMap(); 321 Map<K, V> onlyOnRight = new HashMap<K, V>(right); // will whittle it down 322 Map<K, V> onBoth = newHashMap(); 323 Map<K, MapDifference.ValueDifference<V>> differences = newHashMap(); 324 boolean eq = true; 325 326 for (Entry<? extends K, ? extends V> entry : left.entrySet()) { 327 K leftKey = entry.getKey(); 328 V leftValue = entry.getValue(); 329 if (right.containsKey(leftKey)) { 330 V rightValue = onlyOnRight.remove(leftKey); 331 if (Objects.equal(leftValue, rightValue)) { 332 onBoth.put(leftKey, leftValue); 333 } else { 334 eq = false; 335 differences.put( 336 leftKey, new ValueDifferenceImpl<V>(leftValue, rightValue)); 337 } 338 } else { 339 eq = false; 340 onlyOnLeft.put(leftKey, leftValue); 341 } 342 } 343 344 boolean areEqual = eq && onlyOnRight.isEmpty(); 345 return mapDifference( 346 areEqual, onlyOnLeft, onlyOnRight, onBoth, differences); 347 } 348 349 private static <K, V> MapDifference<K, V> mapDifference(boolean areEqual, 350 Map<K, V> onlyOnLeft, Map<K, V> onlyOnRight, Map<K, V> onBoth, 351 Map<K, ValueDifference<V>> differences) { 352 return new MapDifferenceImpl<K, V>(areEqual, 353 Collections.unmodifiableMap(onlyOnLeft), 354 Collections.unmodifiableMap(onlyOnRight), 355 Collections.unmodifiableMap(onBoth), 356 Collections.unmodifiableMap(differences)); 357 } 358 359 static class MapDifferenceImpl<K, V> implements MapDifference<K, V> { 360 final boolean areEqual; 361 final Map<K, V> onlyOnLeft; 362 final Map<K, V> onlyOnRight; 363 final Map<K, V> onBoth; 364 final Map<K, ValueDifference<V>> differences; 365 366 MapDifferenceImpl(boolean areEqual, Map<K, V> onlyOnLeft, 367 Map<K, V> onlyOnRight, Map<K, V> onBoth, 368 Map<K, ValueDifference<V>> differences) { 369 this.areEqual = areEqual; 370 this.onlyOnLeft = onlyOnLeft; 371 this.onlyOnRight = onlyOnRight; 372 this.onBoth = onBoth; 373 this.differences = differences; 374 } 375 376 public boolean areEqual() { 377 return areEqual; 378 } 379 380 public Map<K, V> entriesOnlyOnLeft() { 381 return onlyOnLeft; 382 } 383 384 public Map<K, V> entriesOnlyOnRight() { 385 return onlyOnRight; 386 } 387 388 public Map<K, V> entriesInCommon() { 389 return onBoth; 390 } 391 392 public Map<K, ValueDifference<V>> entriesDiffering() { 393 return differences; 394 } 395 396 @Override public boolean equals(Object object) { 397 if (object == this) { 398 return true; 399 } 400 if (object instanceof MapDifference) { 401 MapDifference<?, ?> other = (MapDifference<?, ?>) object; 402 return entriesOnlyOnLeft().equals(other.entriesOnlyOnLeft()) 403 && entriesOnlyOnRight().equals(other.entriesOnlyOnRight()) 404 && entriesInCommon().equals(other.entriesInCommon()) 405 && entriesDiffering().equals(other.entriesDiffering()); 406 } 407 return false; 408 } 409 410 @Override public int hashCode() { 411 return Objects.hashCode(entriesOnlyOnLeft(), entriesOnlyOnRight(), 412 entriesInCommon(), entriesDiffering()); 413 } 414 415 @Override public String toString() { 416 if (areEqual) { 417 return "equal"; 418 } 419 420 StringBuilder result = new StringBuilder("not equal"); 421 if (!onlyOnLeft.isEmpty()) { 422 result.append(": only on left=").append(onlyOnLeft); 423 } 424 if (!onlyOnRight.isEmpty()) { 425 result.append(": only on right=").append(onlyOnRight); 426 } 427 if (!differences.isEmpty()) { 428 result.append(": value differences=").append(differences); 429 } 430 return result.toString(); 431 } 432 } 433 434 static class ValueDifferenceImpl<V> 435 implements MapDifference.ValueDifference<V> { 436 private final V left; 437 private final V right; 438 439 ValueDifferenceImpl(@Nullable V left, @Nullable V right) { 440 this.left = left; 441 this.right = right; 442 } 443 444 public V leftValue() { 445 return left; 446 } 447 448 public V rightValue() { 449 return right; 450 } 451 452 @Override public boolean equals(@Nullable Object object) { 453 if (object instanceof MapDifference.ValueDifference<?>) { 454 MapDifference.ValueDifference<?> that = 455 (MapDifference.ValueDifference<?>) object; 456 return Objects.equal(this.left, that.leftValue()) 457 && Objects.equal(this.right, that.rightValue()); 458 } 459 return false; 460 } 461 462 @Override public int hashCode() { 463 return Objects.hashCode(left, right); 464 } 465 466 @Override public String toString() { 467 return "(" + left + ", " + right + ")"; 468 } 469 } 470 471 /** 472 * Returns an immutable map for which the {@link Map#values} are the given 473 * elements in the given order, and each key is the product of invoking a 474 * supplied function on its corresponding value. 475 * 476 * @param values the values to use when constructing the {@code Map} 477 * @param keyFunction the function used to produce the key for each value 478 * @return a map mapping the result of evaluating the function {@code 479 * keyFunction} on each value in the input collection to that value 480 * @throws IllegalArgumentException if {@code keyFunction} produces the same 481 * key for more than one value in the input collection 482 * @throws NullPointerException if any elements of {@code values} is null, or 483 * if {@code keyFunction} produces {@code null} for any value 484 */ 485 public static <K, V> ImmutableMap<K, V> uniqueIndex( 486 Iterable<V> values, Function<? super V, K> keyFunction) { 487 checkNotNull(keyFunction); 488 ImmutableMap.Builder<K, V> builder = ImmutableMap.builder(); 489 for (V value : values) { 490 builder.put(keyFunction.apply(value), value); 491 } 492 return builder.build(); 493 } 494 495 /** 496 * Creates an {@code ImmutableMap<String, String>} from a {@code Properties} 497 * instance. Properties normally derive from {@code Map<Object, Object>}, but 498 * they typically contain strings, which is awkward. This method lets you get 499 * a plain-old-{@code Map} out of a {@code Properties}. 500 * 501 * @param properties a {@code Properties} object to be converted 502 * @return an immutable map containing all the entries in {@code properties} 503 * @throws ClassCastException if any key in {@code Properties} is not a {@code 504 * String} 505 * @throws NullPointerException if any key or value in {@code Properties} is 506 * null 507 */ 508 @GwtIncompatible("java.util.Properties") 509 public static ImmutableMap<String, String> fromProperties( 510 Properties properties) { 511 ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); 512 513 for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) { 514 String key = (String) e.nextElement(); 515 builder.put(key, properties.getProperty(key)); 516 } 517 518 return builder.build(); 519 } 520 521 /** 522 * Returns an immutable map entry with the specified key and value. The {@link 523 * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 524 * 525 * <p>The returned entry is serializable. 526 * 527 * @param key the key to be associated with the returned entry 528 * @param value the value to be associated with the returned entry 529 */ 530 @GwtCompatible(serializable = true) 531 public static <K, V> Entry<K, V> immutableEntry( 532 @Nullable K key, @Nullable V value) { 533 return new ImmutableEntry<K, V>(key, value); 534 } 535 536 /** 537 * Returns an unmodifiable view of the specified set of entries. The {@link 538 * Entry#setValue} operation throws an {@link UnsupportedOperationException}, 539 * as do any operations that would modify the returned set. 540 * 541 * @param entrySet the entries for which to return an unmodifiable view 542 * @return an unmodifiable view of the entries 543 */ 544 static <K, V> Set<Entry<K, V>> unmodifiableEntrySet( 545 Set<Entry<K, V>> entrySet) { 546 return new UnmodifiableEntrySet<K, V>( 547 Collections.unmodifiableSet(entrySet)); 548 } 549 550 /** 551 * Returns an unmodifiable view of the specified map entry. The {@link 552 * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 553 * This also has the side-effect of redefining {@code equals} to comply with 554 * the Entry contract, to avoid a possible nefarious implementation of equals. 555 * 556 * @param entry the entry for which to return an unmodifiable view 557 * @return an unmodifiable view of the entry 558 */ 559 static <K, V> Entry<K, V> unmodifiableEntry(final Entry<K, V> entry) { 560 checkNotNull(entry); 561 return new AbstractMapEntry<K, V>() { 562 @Override public K getKey() { 563 return entry.getKey(); 564 } 565 566 @Override public V getValue() { 567 return entry.getValue(); 568 } 569 }; 570 } 571 572 /** @see Multimaps#unmodifiableEntries */ 573 static class UnmodifiableEntries<K, V> 574 extends ForwardingCollection<Entry<K, V>> { 575 private final Collection<Entry<K, V>> entries; 576 577 UnmodifiableEntries(Collection<Entry<K, V>> entries) { 578 this.entries = entries; 579 } 580 581 @Override protected Collection<Entry<K, V>> delegate() { 582 return entries; 583 } 584 585 @Override public Iterator<Entry<K, V>> iterator() { 586 final Iterator<Entry<K, V>> delegate = super.iterator(); 587 return new ForwardingIterator<Entry<K, V>>() { 588 @Override public Entry<K, V> next() { 589 return unmodifiableEntry(super.next()); 590 } 591 592 @Override public void remove() { 593 throw new UnsupportedOperationException(); 594 } 595 596 @Override protected Iterator<Entry<K, V>> delegate() { 597 return delegate; 598 } 599 }; 600 } 601 602 // See java.util.Collections.UnmodifiableEntrySet for details on attacks. 603 604 @Override public boolean add(Entry<K, V> element) { 605 throw new UnsupportedOperationException(); 606 } 607 608 @Override public boolean addAll( 609 Collection<? extends Entry<K, V>> collection) { 610 throw new UnsupportedOperationException(); 611 } 612 613 @Override public void clear() { 614 throw new UnsupportedOperationException(); 615 } 616 617 @Override public boolean remove(Object object) { 618 throw new UnsupportedOperationException(); 619 } 620 621 @Override public boolean removeAll(Collection<?> collection) { 622 throw new UnsupportedOperationException(); 623 } 624 625 @Override public boolean retainAll(Collection<?> collection) { 626 throw new UnsupportedOperationException(); 627 } 628 629 @Override public Object[] toArray() { 630 return standardToArray(); 631 } 632 633 @Override public <T> T[] toArray(T[] array) { 634 return standardToArray(array); 635 } 636 } 637 638 /** @see Maps#unmodifiableEntrySet(Set) */ 639 static class UnmodifiableEntrySet<K, V> 640 extends UnmodifiableEntries<K, V> implements Set<Entry<K, V>> { 641 UnmodifiableEntrySet(Set<Entry<K, V>> entries) { 642 super(entries); 643 } 644 645 // See java.util.Collections.UnmodifiableEntrySet for details on attacks. 646 647 @Override public boolean equals(@Nullable Object object) { 648 return Sets.equalsImpl(this, object); 649 } 650 651 @Override public int hashCode() { 652 return Sets.hashCodeImpl(this); 653 } 654 } 655 656 /** 657 * Returns an unmodifiable view of the specified bimap. This method allows 658 * modules to provide users with "read-only" access to internal bimaps. Query 659 * operations on the returned bimap "read through" to the specified bimap, and 660 * attemps to modify the returned map, whether direct or via its collection 661 * views, result in an {@code UnsupportedOperationException}. 662 * 663 * <p>The returned bimap will be serializable if the specified bimap is 664 * serializable. 665 * 666 * @param bimap the bimap for which an unmodifiable view is to be returned 667 * @return an unmodifiable view of the specified bimap 668 */ 669 public static <K, V> BiMap<K, V> unmodifiableBiMap( 670 BiMap<? extends K, ? extends V> bimap) { 671 return new UnmodifiableBiMap<K, V>(bimap, null); 672 } 673 674 /** @see Maps#unmodifiableBiMap(BiMap) */ 675 private static class UnmodifiableBiMap<K, V> 676 extends ForwardingMap<K, V> implements BiMap<K, V>, Serializable { 677 final Map<K, V> unmodifiableMap; 678 final BiMap<? extends K, ? extends V> delegate; 679 transient BiMap<V, K> inverse; 680 transient Set<V> values; 681 682 UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate, 683 @Nullable BiMap<V, K> inverse) { 684 unmodifiableMap = Collections.unmodifiableMap(delegate); 685 this.delegate = delegate; 686 this.inverse = inverse; 687 } 688 689 @Override protected Map<K, V> delegate() { 690 return unmodifiableMap; 691 } 692 693 public V forcePut(K key, V value) { 694 throw new UnsupportedOperationException(); 695 } 696 697 public BiMap<V, K> inverse() { 698 BiMap<V, K> result = inverse; 699 return (result == null) 700 ? inverse = new UnmodifiableBiMap<V, K>(delegate.inverse(), this) 701 : result; 702 } 703 704 @Override public Set<V> values() { 705 Set<V> result = values; 706 return (result == null) 707 ? values = Collections.unmodifiableSet(delegate.values()) 708 : result; 709 } 710 711 private static final long serialVersionUID = 0; 712 } 713 714 /** 715 * Returns a view of a map where each value is transformed by a function. All 716 * other properties of the map, such as iteration order, are left intact. For 717 * example, the code: <pre> {@code 718 * 719 * Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9); 720 * Function<Integer, Double> sqrt = 721 * new Function<Integer, Double>() { 722 * public Double apply(Integer in) { 723 * return Math.sqrt((int) in); 724 * } 725 * }; 726 * Map<String, Double> transformed = Maps.transformValues(map, sqrt); 727 * System.out.println(transformed);}</pre> 728 * 729 * ... prints {@code {a=2.0, b=3.0}}. 730 * 731 * <p>Changes in the underlying map are reflected in this view. Conversely, 732 * this view supports removal operations, and these are reflected in the 733 * underlying map. 734 * 735 * <p>It's acceptable for the underlying map to contain null keys, and even 736 * null values provided that the function is capable of accepting null input. 737 * The transformed map might contain null values, if the function sometimes 738 * gives a null result. 739 * 740 * <p>The returned map is not thread-safe or serializable, even if the 741 * underlying map is. 742 * 743 * <p>The function is applied lazily, invoked when needed. This is necessary 744 * for the returned map to be a view, but it means that the function will be 745 * applied many times for bulk operations like {@link Map#containsValue} and 746 * {@code Map.toString()}. For this to perform well, {@code function} should 747 * be fast. To avoid lazy evaluation when the returned map doesn't need to be 748 * a view, copy the returned map into a new map of your choosing. 749 */ 750 public static <K, V1, V2> Map<K, V2> transformValues( 751 Map<K, V1> fromMap, final Function<? super V1, V2> function) { 752 checkNotNull(function); 753 EntryTransformer<K, V1, V2> transformer = 754 new EntryTransformer<K, V1, V2>() { 755 public V2 transformEntry(K key, V1 value) { 756 return function.apply(value); 757 } 758 }; 759 return transformEntries(fromMap, transformer); 760 } 761 762 /** 763 * Returns a view of a map whose values are derived from the original map's 764 * entries. In contrast to {@link #transformValues}, this method's 765 * entry-transformation logic may depend on the key as well as the value. 766 * 767 * <p>All other properties of the transformed map, such as iteration order, 768 * are left intact. For example, the code: <pre> {@code 769 * 770 * Map<String, Boolean> options = 771 * ImmutableMap.of("verbose", true, "sort", false); 772 * EntryTransformer<String, Boolean, String> flagPrefixer = 773 * new EntryTransformer<String, Boolean, String>() { 774 * public String transformEntry(String key, Boolean value) { 775 * return value ? key : "no" + key; 776 * } 777 * }; 778 * Map<String, String> transformed = 779 * Maps.transformEntries(options, flagPrefixer); 780 * System.out.println(transformed);}</pre> 781 * 782 * ... prints {@code {verbose=verbose, sort=nosort}}. 783 * 784 * <p>Changes in the underlying map are reflected in this view. Conversely, 785 * this view supports removal operations, and these are reflected in the 786 * underlying map. 787 * 788 * <p>It's acceptable for the underlying map to contain null keys and null 789 * values provided that the transformer is capable of accepting null inputs. 790 * The transformed map might contain null values if the transformer sometimes 791 * gives a null result. 792 * 793 * <p>The returned map is not thread-safe or serializable, even if the 794 * underlying map is. 795 * 796 * <p>The transformer is applied lazily, invoked when needed. This is 797 * necessary for the returned map to be a view, but it means that the 798 * transformer will be applied many times for bulk operations like {@link 799 * Map#containsValue} and {@link Object#toString}. For this to perform well, 800 * {@code transformer} should be fast. To avoid lazy evaluation when the 801 * returned map doesn't need to be a view, copy the returned map into a new 802 * map of your choosing. 803 * 804 * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 805 * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 806 * that {@code k2} is also of type {@code K}. Using an {@code 807 * EntryTransformer} key type for which this may not hold, such as {@code 808 * ArrayList}, may risk a {@code ClassCastException} when calling methods on 809 * the transformed map. 810 * 811 * @since 7 812 */ 813 @Beta 814 public static <K, V1, V2> Map<K, V2> transformEntries( 815 Map<K, V1> fromMap, 816 EntryTransformer<? super K, ? super V1, V2> transformer) { 817 return new TransformedEntriesMap<K, V1, V2>(fromMap, transformer); 818 } 819 820 /** 821 * A transformation of the value of a key-value pair, using both key and value 822 * as inputs. To apply the transformation to a map, use 823 * {@link Maps#transformEntries(Map, EntryTransformer)}. 824 * 825 * @param <K> the key type of the input and output entries 826 * @param <V1> the value type of the input entry 827 * @param <V2> the value type of the output entry 828 * @since 7 829 */ 830 @Beta 831 public interface EntryTransformer<K, V1, V2> { 832 /** 833 * Determines an output value based on a key-value pair. This method is 834 * <i>generally expected</i>, but not absolutely required, to have the 835 * following properties: 836 * 837 * <ul> 838 * <li>Its execution does not cause any observable side effects. 839 * <li>The computation is <i>consistent with equals</i>; that is, 840 * {@link Objects#equal Objects.equal}{@code (k1, k2) &&} 841 * {@link Objects#equal}{@code (v1, v2)} implies that {@code 842 * Objects.equal(transformer.transform(k1, v1), 843 * transformer.transform(k2, v2))}. 844 * </ul> 845 * 846 * @throws NullPointerException if the key or value is null and this 847 * transformer does not accept null arguments 848 */ 849 V2 transformEntry(@Nullable K key, @Nullable V1 value); 850 } 851 852 static class TransformedEntriesMap<K, V1, V2> 853 extends AbstractMap<K, V2> { 854 final Map<K, V1> fromMap; 855 final EntryTransformer<? super K, ? super V1, V2> transformer; 856 857 TransformedEntriesMap( 858 Map<K, V1> fromMap, 859 EntryTransformer<? super K, ? super V1, V2> transformer) { 860 this.fromMap = checkNotNull(fromMap); 861 this.transformer = checkNotNull(transformer); 862 } 863 864 @Override public int size() { 865 return fromMap.size(); 866 } 867 868 @Override public boolean containsKey(Object key) { 869 return fromMap.containsKey(key); 870 } 871 872 // safe as long as the user followed the <b>Warning</b> in the javadoc 873 @SuppressWarnings("unchecked") 874 @Override public V2 get(Object key) { 875 V1 value = fromMap.get(key); 876 return (value != null || fromMap.containsKey(key)) 877 ? transformer.transformEntry((K) key, value) 878 : null; 879 } 880 881 // safe as long as the user followed the <b>Warning</b> in the javadoc 882 @SuppressWarnings("unchecked") 883 @Override public V2 remove(Object key) { 884 return fromMap.containsKey(key) 885 ? transformer.transformEntry((K) key, fromMap.remove(key)) 886 : null; 887 } 888 889 @Override public void clear() { 890 fromMap.clear(); 891 } 892 893 EntrySet entrySet; 894 895 @Override public Set<Entry<K, V2>> entrySet() { 896 EntrySet result = entrySet; 897 if (result == null) { 898 entrySet = result = new EntrySet(); 899 } 900 return result; 901 } 902 903 class EntrySet extends AbstractSet<Entry<K, V2>> { 904 @Override public int size() { 905 return TransformedEntriesMap.this.size(); 906 } 907 908 @Override public Iterator<Entry<K, V2>> iterator() { 909 final Iterator<Entry<K, V1>> mapIterator = 910 fromMap.entrySet().iterator(); 911 912 return new Iterator<Entry<K, V2>>() { 913 public boolean hasNext() { 914 return mapIterator.hasNext(); 915 } 916 917 public Entry<K, V2> next() { 918 final Entry<K, V1> entry = mapIterator.next(); 919 return new AbstractMapEntry<K, V2>() { 920 @Override public K getKey() { 921 return entry.getKey(); 922 } 923 924 @Override public V2 getValue() { 925 return transformer.transformEntry( 926 entry.getKey(), entry.getValue()); 927 } 928 }; 929 } 930 931 public void remove() { 932 mapIterator.remove(); 933 } 934 }; 935 } 936 937 @Override public void clear() { 938 fromMap.clear(); 939 } 940 941 @Override public boolean contains(Object o) { 942 if (!(o instanceof Entry)) { 943 return false; 944 } 945 Entry<?, ?> entry = (Entry<?, ?>) o; 946 Object entryKey = entry.getKey(); 947 Object entryValue = entry.getValue(); 948 V2 mapValue = TransformedEntriesMap.this.get(entryKey); 949 if (mapValue != null) { 950 return mapValue.equals(entryValue); 951 } 952 return entryValue == null && containsKey(entryKey); 953 } 954 955 @Override public boolean remove(Object o) { 956 if (contains(o)) { 957 Entry<?, ?> entry = (Entry<?, ?>) o; 958 Object key = entry.getKey(); 959 fromMap.remove(key); 960 return true; 961 } 962 return false; 963 } 964 } 965 } 966 967 /** 968 * Returns a map containing the mappings in {@code unfiltered} whose keys 969 * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 970 * changes to one affect the other. 971 * 972 * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 973 * values()} views have iterators that don't support {@code remove()}, but all 974 * other methods are supported by the map and its views. When given a key that 975 * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()} 976 * methods throw an {@link IllegalArgumentException}. 977 * 978 * <p>When methods such as {@code removeAll()} and {@code clear()} are called 979 * on the filtered map or its views, only mappings whose keys satisfy the 980 * filter will be removed from the underlying map. 981 * 982 * <p>The returned map isn't threadsafe or serializable, even if {@code 983 * unfiltered} is. 984 * 985 * <p>Many of the filtered map's methods, such as {@code size()}, 986 * iterate across every key/value mapping in the underlying map and determine 987 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 988 * faster to copy the filtered map and use the copy. 989 * 990 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with 991 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 992 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 993 * inconsistent with equals. 994 */ 995 public static <K, V> Map<K, V> filterKeys( 996 Map<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 997 checkNotNull(keyPredicate); 998 Predicate<Entry<K, V>> entryPredicate = 999 new Predicate<Entry<K, V>>() { 1000 public boolean apply(Entry<K, V> input) { 1001 return keyPredicate.apply(input.getKey()); 1002 } 1003 }; 1004 return (unfiltered instanceof AbstractFilteredMap) 1005 ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate) 1006 : new FilteredKeyMap<K, V>( 1007 checkNotNull(unfiltered), keyPredicate, entryPredicate); 1008 } 1009 1010 /** 1011 * Returns a map containing the mappings in {@code unfiltered} whose values 1012 * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 1013 * changes to one affect the other. 1014 * 1015 * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 1016 * values()} views have iterators that don't support {@code remove()}, but all 1017 * other methods are supported by the map and its views. When given a value 1018 * that doesn't satisfy the predicate, the map's {@code put()}, {@code 1019 * putAll()}, and {@link Entry#setValue} methods throw an {@link 1020 * IllegalArgumentException}. 1021 * 1022 * <p>When methods such as {@code removeAll()} and {@code clear()} are called 1023 * on the filtered map or its views, only mappings whose values satisfy the 1024 * filter will be removed from the underlying map. 1025 * 1026 * <p>The returned map isn't threadsafe or serializable, even if {@code 1027 * unfiltered} is. 1028 * 1029 * <p>Many of the filtered map's methods, such as {@code size()}, 1030 * iterate across every key/value mapping in the underlying map and determine 1031 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1032 * faster to copy the filtered map and use the copy. 1033 * 1034 * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 1035 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 1036 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 1037 * inconsistent with equals. 1038 */ 1039 public static <K, V> Map<K, V> filterValues( 1040 Map<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 1041 checkNotNull(valuePredicate); 1042 Predicate<Entry<K, V>> entryPredicate = 1043 new Predicate<Entry<K, V>>() { 1044 public boolean apply(Entry<K, V> input) { 1045 return valuePredicate.apply(input.getValue()); 1046 } 1047 }; 1048 return filterEntries(unfiltered, entryPredicate); 1049 } 1050 1051 /** 1052 * Returns a map containing the mappings in {@code unfiltered} that satisfy a 1053 * predicate. The returned map is a live view of {@code unfiltered}; changes 1054 * to one affect the other. 1055 * 1056 * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 1057 * values()} views have iterators that don't support {@code remove()}, but all 1058 * other methods are supported by the map and its views. When given a 1059 * key/value pair that doesn't satisfy the predicate, the map's {@code put()} 1060 * and {@code putAll()} methods throw an {@link IllegalArgumentException}. 1061 * Similarly, the map's entries have a {@link Entry#setValue} method that 1062 * throws an {@link IllegalArgumentException} when the existing key and the 1063 * provided value don't satisfy the predicate. 1064 * 1065 * <p>When methods such as {@code removeAll()} and {@code clear()} are called 1066 * on the filtered map or its views, only mappings that satisfy the filter 1067 * will be removed from the underlying map. 1068 * 1069 * <p>The returned map isn't threadsafe or serializable, even if {@code 1070 * unfiltered} is. 1071 * 1072 * <p>Many of the filtered map's methods, such as {@code size()}, 1073 * iterate across every key/value mapping in the underlying map and determine 1074 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1075 * faster to copy the filtered map and use the copy. 1076 * 1077 * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 1078 * equals</i>, as documented at {@link Predicate#apply}. 1079 */ 1080 public static <K, V> Map<K, V> filterEntries( 1081 Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 1082 checkNotNull(entryPredicate); 1083 return (unfiltered instanceof AbstractFilteredMap) 1084 ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate) 1085 : new FilteredEntryMap<K, V>(checkNotNull(unfiltered), entryPredicate); 1086 } 1087 1088 /** 1089 * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when 1090 * filtering a filtered map. 1091 */ 1092 private static <K, V> Map<K, V> filterFiltered(AbstractFilteredMap<K, V> map, 1093 Predicate<? super Entry<K, V>> entryPredicate) { 1094 Predicate<Entry<K, V>> predicate = 1095 Predicates.and(map.predicate, entryPredicate); 1096 return new FilteredEntryMap<K, V>(map.unfiltered, predicate); 1097 } 1098 1099 private abstract static class AbstractFilteredMap<K, V> 1100 extends AbstractMap<K, V> { 1101 final Map<K, V> unfiltered; 1102 final Predicate<? super Entry<K, V>> predicate; 1103 1104 AbstractFilteredMap( 1105 Map<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) { 1106 this.unfiltered = unfiltered; 1107 this.predicate = predicate; 1108 } 1109 1110 boolean apply(Object key, V value) { 1111 // This method is called only when the key is in the map, implying that 1112 // key is a K. 1113 @SuppressWarnings("unchecked") 1114 K k = (K) key; 1115 return predicate.apply(Maps.immutableEntry(k, value)); 1116 } 1117 1118 @Override public V put(K key, V value) { 1119 checkArgument(apply(key, value)); 1120 return unfiltered.put(key, value); 1121 } 1122 1123 @Override public void putAll(Map<? extends K, ? extends V> map) { 1124 for (Entry<? extends K, ? extends V> entry : map.entrySet()) { 1125 checkArgument(apply(entry.getKey(), entry.getValue())); 1126 } 1127 unfiltered.putAll(map); 1128 } 1129 1130 @Override public boolean containsKey(Object key) { 1131 return unfiltered.containsKey(key) && apply(key, unfiltered.get(key)); 1132 } 1133 1134 @Override public V get(Object key) { 1135 V value = unfiltered.get(key); 1136 return ((value != null) && apply(key, value)) ? value : null; 1137 } 1138 1139 @Override public boolean isEmpty() { 1140 return entrySet().isEmpty(); 1141 } 1142 1143 @Override public V remove(Object key) { 1144 return containsKey(key) ? unfiltered.remove(key) : null; 1145 } 1146 1147 Collection<V> values; 1148 1149 @Override public Collection<V> values() { 1150 Collection<V> result = values; 1151 return (result == null) ? values = new Values() : result; 1152 } 1153 1154 class Values extends AbstractCollection<V> { 1155 @Override public Iterator<V> iterator() { 1156 final Iterator<Entry<K, V>> entryIterator = entrySet().iterator(); 1157 return new UnmodifiableIterator<V>() { 1158 public boolean hasNext() { 1159 return entryIterator.hasNext(); 1160 } 1161 1162 public V next() { 1163 return entryIterator.next().getValue(); 1164 } 1165 }; 1166 } 1167 1168 @Override public int size() { 1169 return entrySet().size(); 1170 } 1171 1172 @Override public void clear() { 1173 entrySet().clear(); 1174 } 1175 1176 @Override public boolean isEmpty() { 1177 return entrySet().isEmpty(); 1178 } 1179 1180 @Override public boolean remove(Object o) { 1181 Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 1182 while (iterator.hasNext()) { 1183 Entry<K, V> entry = iterator.next(); 1184 if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) { 1185 iterator.remove(); 1186 return true; 1187 } 1188 } 1189 return false; 1190 } 1191 1192 @Override public boolean removeAll(Collection<?> collection) { 1193 checkNotNull(collection); 1194 boolean changed = false; 1195 Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 1196 while (iterator.hasNext()) { 1197 Entry<K, V> entry = iterator.next(); 1198 if (collection.contains(entry.getValue()) && predicate.apply(entry)) { 1199 iterator.remove(); 1200 changed = true; 1201 } 1202 } 1203 return changed; 1204 } 1205 1206 @Override public boolean retainAll(Collection<?> collection) { 1207 checkNotNull(collection); 1208 boolean changed = false; 1209 Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 1210 while (iterator.hasNext()) { 1211 Entry<K, V> entry = iterator.next(); 1212 if (!collection.contains(entry.getValue()) 1213 && predicate.apply(entry)) { 1214 iterator.remove(); 1215 changed = true; 1216 } 1217 } 1218 return changed; 1219 } 1220 1221 @Override public Object[] toArray() { 1222 // creating an ArrayList so filtering happens once 1223 return Lists.newArrayList(iterator()).toArray(); 1224 } 1225 1226 @Override public <T> T[] toArray(T[] array) { 1227 return Lists.newArrayList(iterator()).toArray(array); 1228 } 1229 } 1230 } 1231 1232 private static class FilteredKeyMap<K, V> extends AbstractFilteredMap<K, V> { 1233 Predicate<? super K> keyPredicate; 1234 1235 FilteredKeyMap(Map<K, V> unfiltered, Predicate<? super K> keyPredicate, 1236 Predicate<Entry<K, V>> entryPredicate) { 1237 super(unfiltered, entryPredicate); 1238 this.keyPredicate = keyPredicate; 1239 } 1240 1241 Set<Entry<K, V>> entrySet; 1242 1243 @Override public Set<Entry<K, V>> entrySet() { 1244 Set<Entry<K, V>> result = entrySet; 1245 return (result == null) 1246 ? entrySet = Sets.filter(unfiltered.entrySet(), predicate) 1247 : result; 1248 } 1249 1250 Set<K> keySet; 1251 1252 @Override public Set<K> keySet() { 1253 Set<K> result = keySet; 1254 return (result == null) 1255 ? keySet = Sets.filter(unfiltered.keySet(), keyPredicate) 1256 : result; 1257 } 1258 1259 // The cast is called only when the key is in the unfiltered map, implying 1260 // that key is a K. 1261 @Override 1262 @SuppressWarnings("unchecked") 1263 public boolean containsKey(Object key) { 1264 return unfiltered.containsKey(key) && keyPredicate.apply((K) key); 1265 } 1266 } 1267 1268 static class FilteredEntryMap<K, V> extends AbstractFilteredMap<K, V> { 1269 /** 1270 * Entries in this set satisfy the predicate, but they don't validate the 1271 * input to {@code Entry.setValue()}. 1272 */ 1273 final Set<Entry<K, V>> filteredEntrySet; 1274 1275 FilteredEntryMap( 1276 Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 1277 super(unfiltered, entryPredicate); 1278 filteredEntrySet = Sets.filter(unfiltered.entrySet(), predicate); 1279 } 1280 1281 Set<Entry<K, V>> entrySet; 1282 1283 @Override public Set<Entry<K, V>> entrySet() { 1284 Set<Entry<K, V>> result = entrySet; 1285 return (result == null) ? entrySet = new EntrySet() : result; 1286 } 1287 1288 private class EntrySet extends ForwardingSet<Entry<K, V>> { 1289 @Override protected Set<Entry<K, V>> delegate() { 1290 return filteredEntrySet; 1291 } 1292 1293 @Override public Iterator<Entry<K, V>> iterator() { 1294 final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator(); 1295 return new UnmodifiableIterator<Entry<K, V>>() { 1296 public boolean hasNext() { 1297 return iterator.hasNext(); 1298 } 1299 1300 public Entry<K, V> next() { 1301 final Entry<K, V> entry = iterator.next(); 1302 return new ForwardingMapEntry<K, V>() { 1303 @Override protected Entry<K, V> delegate() { 1304 return entry; 1305 } 1306 1307 @Override public V setValue(V value) { 1308 checkArgument(apply(entry.getKey(), value)); 1309 return super.setValue(value); 1310 } 1311 }; 1312 } 1313 }; 1314 } 1315 } 1316 1317 Set<K> keySet; 1318 1319 @Override public Set<K> keySet() { 1320 Set<K> result = keySet; 1321 return (result == null) ? keySet = new KeySet() : result; 1322 } 1323 1324 private class KeySet extends AbstractSet<K> { 1325 @Override public Iterator<K> iterator() { 1326 final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator(); 1327 return new UnmodifiableIterator<K>() { 1328 public boolean hasNext() { 1329 return iterator.hasNext(); 1330 } 1331 1332 public K next() { 1333 return iterator.next().getKey(); 1334 } 1335 }; 1336 } 1337 1338 @Override public int size() { 1339 return filteredEntrySet.size(); 1340 } 1341 1342 @Override public void clear() { 1343 filteredEntrySet.clear(); 1344 } 1345 1346 @Override public boolean contains(Object o) { 1347 return containsKey(o); 1348 } 1349 1350 @Override public boolean remove(Object o) { 1351 if (containsKey(o)) { 1352 unfiltered.remove(o); 1353 return true; 1354 } 1355 return false; 1356 } 1357 1358 @Override public boolean removeAll(Collection<?> collection) { 1359 checkNotNull(collection); // for GWT 1360 boolean changed = false; 1361 for (Object obj : collection) { 1362 changed |= remove(obj); 1363 } 1364 return changed; 1365 } 1366 1367 @Override public boolean retainAll(Collection<?> collection) { 1368 checkNotNull(collection); // for GWT 1369 boolean changed = false; 1370 Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 1371 while (iterator.hasNext()) { 1372 Entry<K, V> entry = iterator.next(); 1373 if (!collection.contains(entry.getKey()) && predicate.apply(entry)) { 1374 iterator.remove(); 1375 changed = true; 1376 } 1377 } 1378 return changed; 1379 } 1380 1381 @Override public Object[] toArray() { 1382 // creating an ArrayList so filtering happens once 1383 return Lists.newArrayList(iterator()).toArray(); 1384 } 1385 1386 @Override public <T> T[] toArray(T[] array) { 1387 return Lists.newArrayList(iterator()).toArray(array); 1388 } 1389 } 1390 } 1391 1392 /** 1393 * {@code AbstractMap} extension that implements {@link #isEmpty()} as {@code 1394 * entrySet().isEmpty()} instead of {@code size() == 0} to speed up 1395 * implementations where {@code size()} is O(n), and it delegates the {@code 1396 * isEmpty()} methods of its key set and value collection to this 1397 * implementation. 1398 */ 1399 @GwtCompatible 1400 abstract static class ImprovedAbstractMap<K, V> extends AbstractMap<K, V> { 1401 /** 1402 * Creates the entry set to be returned by {@link #entrySet()}. This method 1403 * is invoked at most once on a given map, at the time when {@code entrySet} 1404 * is first called. 1405 */ 1406 protected abstract Set<Entry<K, V>> createEntrySet(); 1407 1408 private Set<Entry<K, V>> entrySet; 1409 1410 @Override public Set<Entry<K, V>> entrySet() { 1411 Set<Entry<K, V>> result = entrySet; 1412 if (result == null) { 1413 entrySet = result = createEntrySet(); 1414 } 1415 return result; 1416 } 1417 1418 private Set<K> keySet; 1419 1420 @Override public Set<K> keySet() { 1421 Set<K> result = keySet; 1422 if (result == null) { 1423 final Set<K> delegate = super.keySet(); 1424 keySet = result = new ForwardingSet<K>() { 1425 @Override protected Set<K> delegate() { 1426 return delegate; 1427 } 1428 1429 @Override public boolean isEmpty() { 1430 return ImprovedAbstractMap.this.isEmpty(); 1431 } 1432 1433 @Override public boolean remove(Object object) { 1434 if (contains(object)) { 1435 ImprovedAbstractMap.this.remove(object); 1436 return true; 1437 } 1438 return false; 1439 } 1440 }; 1441 } 1442 return result; 1443 } 1444 1445 private Collection<V> values; 1446 1447 @Override public Collection<V> values() { 1448 Collection<V> result = values; 1449 if (result == null) { 1450 final Collection<V> delegate = super.values(); 1451 values = result = new ForwardingCollection<V>() { 1452 @Override protected Collection<V> delegate() { 1453 return delegate; 1454 } 1455 1456 @Override public boolean isEmpty() { 1457 return ImprovedAbstractMap.this.isEmpty(); 1458 } 1459 }; 1460 } 1461 return result; 1462 } 1463 1464 /** 1465 * Returns {@code true} if this map contains no key-value mappings. 1466 * 1467 * <p>The implementation returns {@code entrySet().isEmpty()}. 1468 * 1469 * @return {@code true} if this map contains no key-value mappings 1470 */ 1471 @Override public boolean isEmpty() { 1472 return entrySet().isEmpty(); 1473 } 1474 } 1475 1476 static final MapJoiner STANDARD_JOINER = 1477 Collections2.STANDARD_JOINER.withKeyValueSeparator("="); 1478 1479 /** 1480 * Delegates to {@link Map#get}. Returns {@code null} on {@code 1481 * ClassCastException}. 1482 */ 1483 static <V> V safeGet(Map<?, V> map, Object key) { 1484 try { 1485 return map.get(key); 1486 } catch (ClassCastException e) { 1487 return null; 1488 } 1489 } 1490 1491 /** 1492 * Delegates to {@link Map#containsKey}. Returns {@code false} on {@code 1493 * ClassCastException} 1494 */ 1495 static boolean safeContainsKey(Map<?, ?> map, Object key) { 1496 try { 1497 return map.containsKey(key); 1498 } catch (ClassCastException e) { 1499 return false; 1500 } 1501 } 1502 1503 /** 1504 * An implementation of {@link Map#entrySet}. 1505 */ 1506 static <K, V> Set<Entry<K, V>> entrySetImpl( 1507 Map<K, V> map, Supplier<Iterator<Entry<K, V>>> entryIteratorSupplier) { 1508 return new EntrySetImpl<K, V>(map, entryIteratorSupplier); 1509 } 1510 1511 private static class EntrySetImpl<K, V> extends AbstractSet<Entry<K, V>> { 1512 private final Map<K, V> map; 1513 private final Supplier<Iterator<Entry<K, V>>> entryIteratorSupplier; 1514 1515 EntrySetImpl( 1516 Map<K, V> map, Supplier<Iterator<Entry<K, V>>> entryIteratorSupplier) { 1517 this.map = checkNotNull(map); 1518 this.entryIteratorSupplier = checkNotNull(entryIteratorSupplier); 1519 } 1520 1521 @Override public Iterator<Entry<K, V>> iterator() { 1522 return entryIteratorSupplier.get(); 1523 } 1524 1525 @Override public int size() { 1526 return map.size(); 1527 } 1528 1529 @Override public void clear() { 1530 map.clear(); 1531 } 1532 1533 @Override public boolean contains(Object o) { 1534 if (o instanceof Entry) { 1535 Entry<?, ?> entry = (Entry<?, ?>) o; 1536 Object key = entry.getKey(); 1537 if (map.containsKey(key)) { 1538 V value = map.get(entry.getKey()); 1539 return Objects.equal(value, entry.getValue()); 1540 } 1541 } 1542 return false; 1543 } 1544 1545 @Override public boolean isEmpty() { 1546 return map.isEmpty(); 1547 } 1548 1549 @Override public boolean remove(Object o) { 1550 if (contains(o)) { 1551 Entry<?, ?> entry = (Entry<?, ?>) o; 1552 map.remove(entry.getKey()); 1553 return true; 1554 } 1555 return false; 1556 } 1557 1558 @Override public int hashCode() { 1559 return map.hashCode(); 1560 } 1561 } 1562 1563 /** 1564 * Implements {@code Collection.contains} safely for forwarding collections of 1565 * map entries. If {@code o} is an instance of {@code Map.Entry}, it is 1566 * wrapped using {@link #unmodifiableEntry} to protect against a possible 1567 * nefarious equals method. 1568 * 1569 * <p>Note that {@code c} is the backing (delegate) collection, rather than 1570 * the forwarding collection. 1571 * 1572 * @param c the delegate (unwrapped) collection of map entries 1573 * @param o the object that might be contained in {@code c} 1574 * @return {@code true} if {@code c} contains {@code o} 1575 */ 1576 static <K, V> boolean containsEntryImpl(Collection<Entry<K, V>> c, Object o) { 1577 if (!(o instanceof Entry)) { 1578 return false; 1579 } 1580 return c.contains(unmodifiableEntry((Entry<?, ?>) o)); 1581 } 1582 1583 /** 1584 * Implements {@code Collection.remove} safely for forwarding collections of 1585 * map entries. If {@code o} is an instance of {@code Map.Entry}, it is 1586 * wrapped using {@link #unmodifiableEntry} to protect against a possible 1587 * nefarious equals method. 1588 * 1589 * <p>Note that {@code c} is backing (delegate) collection, rather than the 1590 * forwarding collection. 1591 * 1592 * @param c the delegate (unwrapped) collection of map entries 1593 * @param o the object to remove from {@code c} 1594 * @return {@code true} if {@code c} was changed 1595 */ 1596 static <K, V> boolean removeEntryImpl(Collection<Entry<K, V>> c, Object o) { 1597 if (!(o instanceof Entry)) { 1598 return false; 1599 } 1600 return c.remove(unmodifiableEntry((Entry<?, ?>) o)); 1601 } 1602 1603 /** 1604 * An implementation of {@link Map#equals}. 1605 */ 1606 static boolean equalsImpl(Map<?, ?> map, Object object) { 1607 if (map == object) { 1608 return true; 1609 } 1610 if (object instanceof Map) { 1611 Map<?, ?> o = (Map<?, ?>) object; 1612 return map.entrySet().equals(o.entrySet()); 1613 } 1614 return false; 1615 } 1616 1617 /** 1618 * An implementation of {@link Map#hashCode}. 1619 */ 1620 static int hashCodeImpl(Map<?, ?> map) { 1621 return Sets.hashCodeImpl(map.entrySet()); 1622 } 1623 1624 /** 1625 * An implementation of {@link Map#toString}. 1626 */ 1627 static String toStringImpl(Map<?, ?> map) { 1628 StringBuilder sb 1629 = Collections2.newStringBuilderForCollection(map.size()).append('{'); 1630 STANDARD_JOINER.appendTo(sb, map); 1631 return sb.append('}').toString(); 1632 } 1633 1634 /** 1635 * An implementation of {@link Map#putAll}. 1636 */ 1637 static <K, V> void putAllImpl( 1638 Map<K, V> self, Map<? extends K, ? extends V> map) { 1639 for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { 1640 self.put(entry.getKey(), entry.getValue()); 1641 } 1642 } 1643 1644 /** 1645 * An implementation of {@link Map#keySet}. 1646 */ 1647 static <K, V> Set<K> keySetImpl(final Map<K, V> map) { 1648 return new AbstractMapWrapper<K, V>(map).keySet(); 1649 } 1650 1651 /** 1652 * An admittedly inefficient implementation of {@link Map#containsKey}. 1653 */ 1654 static boolean containsKeyImpl(Map<?, ?> map, @Nullable Object key) { 1655 for (Entry<?, ?> entry : map.entrySet()) { 1656 if (Objects.equal(entry.getKey(), key)) { 1657 return true; 1658 } 1659 } 1660 return false; 1661 } 1662 1663 /** 1664 * An implementation of {@link Map#values}. 1665 */ 1666 static <K, V> Collection<V> valuesImpl(Map<K, V> map) { 1667 return new AbstractMapWrapper<K, V>(map).values(); 1668 } 1669 1670 /** 1671 * An implementation of {@link Map#containsValue}. 1672 */ 1673 static boolean containsValueImpl(Map<?, ?> map, @Nullable Object value) { 1674 for (Entry<?, ?> entry : map.entrySet()) { 1675 if (Objects.equal(entry.getValue(), value)) { 1676 return true; 1677 } 1678 } 1679 return false; 1680 } 1681 1682 /** 1683 * A wrapper on a map that supplies the {@code ImprovedAbstractMap} 1684 * implementations of {@code keySet()} and {@code values()}. 1685 */ 1686 private static final class AbstractMapWrapper<K, V> 1687 extends ImprovedAbstractMap<K, V>{ 1688 private final Map<K, V> map; 1689 1690 AbstractMapWrapper(Map<K, V> map) { 1691 this.map = checkNotNull(map); 1692 } 1693 1694 @Override public void clear() { 1695 map.clear(); 1696 } 1697 1698 @Override public boolean containsKey(Object key) { 1699 return map.containsKey(key); 1700 } 1701 1702 @Override public V remove(Object key) { 1703 return map.remove(key); 1704 } 1705 1706 @Override public boolean containsValue(Object value) { 1707 return map.containsValue(value); 1708 } 1709 1710 @Override protected Set<Entry<K, V>> createEntrySet() { 1711 return map.entrySet(); 1712 } 1713 1714 @Override public boolean isEmpty() { 1715 return map.isEmpty(); 1716 } 1717 1718 @Override public int size() { 1719 return map.size(); 1720 } 1721 } 1722 }