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 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 @Override 377 public boolean areEqual() { 378 return areEqual; 379 } 380 381 @Override 382 public Map<K, V> entriesOnlyOnLeft() { 383 return onlyOnLeft; 384 } 385 386 @Override 387 public Map<K, V> entriesOnlyOnRight() { 388 return onlyOnRight; 389 } 390 391 @Override 392 public Map<K, V> entriesInCommon() { 393 return onBoth; 394 } 395 396 @Override 397 public Map<K, ValueDifference<V>> entriesDiffering() { 398 return differences; 399 } 400 401 @Override public boolean equals(Object object) { 402 if (object == this) { 403 return true; 404 } 405 if (object instanceof MapDifference) { 406 MapDifference<?, ?> other = (MapDifference<?, ?>) object; 407 return entriesOnlyOnLeft().equals(other.entriesOnlyOnLeft()) 408 && entriesOnlyOnRight().equals(other.entriesOnlyOnRight()) 409 && entriesInCommon().equals(other.entriesInCommon()) 410 && entriesDiffering().equals(other.entriesDiffering()); 411 } 412 return false; 413 } 414 415 @Override public int hashCode() { 416 return Objects.hashCode(entriesOnlyOnLeft(), entriesOnlyOnRight(), 417 entriesInCommon(), entriesDiffering()); 418 } 419 420 @Override public String toString() { 421 if (areEqual) { 422 return "equal"; 423 } 424 425 StringBuilder result = new StringBuilder("not equal"); 426 if (!onlyOnLeft.isEmpty()) { 427 result.append(": only on left=").append(onlyOnLeft); 428 } 429 if (!onlyOnRight.isEmpty()) { 430 result.append(": only on right=").append(onlyOnRight); 431 } 432 if (!differences.isEmpty()) { 433 result.append(": value differences=").append(differences); 434 } 435 return result.toString(); 436 } 437 } 438 439 static class ValueDifferenceImpl<V> 440 implements MapDifference.ValueDifference<V> { 441 private final V left; 442 private final V right; 443 444 ValueDifferenceImpl(@Nullable V left, @Nullable V right) { 445 this.left = left; 446 this.right = right; 447 } 448 449 @Override 450 public V leftValue() { 451 return left; 452 } 453 454 @Override 455 public V rightValue() { 456 return right; 457 } 458 459 @Override public boolean equals(@Nullable Object object) { 460 if (object instanceof MapDifference.ValueDifference<?>) { 461 MapDifference.ValueDifference<?> that = 462 (MapDifference.ValueDifference<?>) object; 463 return Objects.equal(this.left, that.leftValue()) 464 && Objects.equal(this.right, that.rightValue()); 465 } 466 return false; 467 } 468 469 @Override public int hashCode() { 470 return Objects.hashCode(left, right); 471 } 472 473 @Override public String toString() { 474 return "(" + left + ", " + right + ")"; 475 } 476 } 477 478 /** 479 * Returns an immutable map for which the {@link Map#values} are the given 480 * elements in the given order, and each key is the product of invoking a 481 * supplied function on its corresponding value. 482 * 483 * @param values the values to use when constructing the {@code Map} 484 * @param keyFunction the function used to produce the key for each value 485 * @return a map mapping the result of evaluating the function {@code 486 * keyFunction} on each value in the input collection to that value 487 * @throws IllegalArgumentException if {@code keyFunction} produces the same 488 * key for more than one value in the input collection 489 * @throws NullPointerException if any elements of {@code values} is null, or 490 * if {@code keyFunction} produces {@code null} for any value 491 */ 492 public static <K, V> ImmutableMap<K, V> uniqueIndex( 493 Iterable<V> values, Function<? super V, K> keyFunction) { 494 checkNotNull(keyFunction); 495 ImmutableMap.Builder<K, V> builder = ImmutableMap.builder(); 496 for (V value : values) { 497 builder.put(keyFunction.apply(value), value); 498 } 499 return builder.build(); 500 } 501 502 /** 503 * Creates an {@code ImmutableMap<String, String>} from a {@code Properties} 504 * instance. Properties normally derive from {@code Map<Object, Object>}, but 505 * they typically contain strings, which is awkward. This method lets you get 506 * a plain-old-{@code Map} out of a {@code Properties}. 507 * 508 * @param properties a {@code Properties} object to be converted 509 * @return an immutable map containing all the entries in {@code properties} 510 * @throws ClassCastException if any key in {@code Properties} is not a {@code 511 * String} 512 * @throws NullPointerException if any key or value in {@code Properties} is 513 * null 514 */ 515 @GwtIncompatible("java.util.Properties") 516 public static ImmutableMap<String, String> fromProperties( 517 Properties properties) { 518 ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); 519 520 for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) { 521 String key = (String) e.nextElement(); 522 builder.put(key, properties.getProperty(key)); 523 } 524 525 return builder.build(); 526 } 527 528 /** 529 * Returns an immutable map entry with the specified key and value. The {@link 530 * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 531 * 532 * <p>The returned entry is serializable. 533 * 534 * @param key the key to be associated with the returned entry 535 * @param value the value to be associated with the returned entry 536 */ 537 @GwtCompatible(serializable = true) 538 public static <K, V> Entry<K, V> immutableEntry( 539 @Nullable K key, @Nullable V value) { 540 return new ImmutableEntry<K, V>(key, value); 541 } 542 543 /** 544 * Returns an unmodifiable view of the specified set of entries. The {@link 545 * Entry#setValue} operation throws an {@link UnsupportedOperationException}, 546 * as do any operations that would modify the returned set. 547 * 548 * @param entrySet the entries for which to return an unmodifiable view 549 * @return an unmodifiable view of the entries 550 */ 551 static <K, V> Set<Entry<K, V>> unmodifiableEntrySet( 552 Set<Entry<K, V>> entrySet) { 553 return new UnmodifiableEntrySet<K, V>( 554 Collections.unmodifiableSet(entrySet)); 555 } 556 557 /** 558 * Returns an unmodifiable view of the specified map entry. The {@link 559 * Entry#setValue} operation throws an {@link UnsupportedOperationException}. 560 * This also has the side-effect of redefining {@code equals} to comply with 561 * the Entry contract, to avoid a possible nefarious implementation of equals. 562 * 563 * @param entry the entry for which to return an unmodifiable view 564 * @return an unmodifiable view of the entry 565 */ 566 static <K, V> Entry<K, V> unmodifiableEntry(final Entry<K, V> entry) { 567 checkNotNull(entry); 568 return new AbstractMapEntry<K, V>() { 569 @Override public K getKey() { 570 return entry.getKey(); 571 } 572 573 @Override public V getValue() { 574 return entry.getValue(); 575 } 576 }; 577 } 578 579 /** @see Multimaps#unmodifiableEntries */ 580 static class UnmodifiableEntries<K, V> 581 extends ForwardingCollection<Entry<K, V>> { 582 private final Collection<Entry<K, V>> entries; 583 584 UnmodifiableEntries(Collection<Entry<K, V>> entries) { 585 this.entries = entries; 586 } 587 588 @Override protected Collection<Entry<K, V>> delegate() { 589 return entries; 590 } 591 592 @Override public Iterator<Entry<K, V>> iterator() { 593 final Iterator<Entry<K, V>> delegate = super.iterator(); 594 return new ForwardingIterator<Entry<K, V>>() { 595 @Override public Entry<K, V> next() { 596 return unmodifiableEntry(super.next()); 597 } 598 599 @Override public void remove() { 600 throw new UnsupportedOperationException(); 601 } 602 603 @Override protected Iterator<Entry<K, V>> delegate() { 604 return delegate; 605 } 606 }; 607 } 608 609 // See java.util.Collections.UnmodifiableEntrySet for details on attacks. 610 611 @Override public boolean add(Entry<K, V> element) { 612 throw new UnsupportedOperationException(); 613 } 614 615 @Override public boolean addAll( 616 Collection<? extends Entry<K, V>> collection) { 617 throw new UnsupportedOperationException(); 618 } 619 620 @Override public void clear() { 621 throw new UnsupportedOperationException(); 622 } 623 624 @Override public boolean remove(Object object) { 625 throw new UnsupportedOperationException(); 626 } 627 628 @Override public boolean removeAll(Collection<?> collection) { 629 throw new UnsupportedOperationException(); 630 } 631 632 @Override public boolean retainAll(Collection<?> collection) { 633 throw new UnsupportedOperationException(); 634 } 635 636 @Override public Object[] toArray() { 637 return standardToArray(); 638 } 639 640 @Override public <T> T[] toArray(T[] array) { 641 return standardToArray(array); 642 } 643 } 644 645 /** @see Maps#unmodifiableEntrySet(Set) */ 646 static class UnmodifiableEntrySet<K, V> 647 extends UnmodifiableEntries<K, V> implements Set<Entry<K, V>> { 648 UnmodifiableEntrySet(Set<Entry<K, V>> entries) { 649 super(entries); 650 } 651 652 // See java.util.Collections.UnmodifiableEntrySet for details on attacks. 653 654 @Override public boolean equals(@Nullable Object object) { 655 return Sets.equalsImpl(this, object); 656 } 657 658 @Override public int hashCode() { 659 return Sets.hashCodeImpl(this); 660 } 661 } 662 663 /** 664 * Returns an unmodifiable view of the specified bimap. This method allows 665 * modules to provide users with "read-only" access to internal bimaps. Query 666 * operations on the returned bimap "read through" to the specified bimap, and 667 * attemps to modify the returned map, whether direct or via its collection 668 * views, result in an {@code UnsupportedOperationException}. 669 * 670 * <p>The returned bimap will be serializable if the specified bimap is 671 * serializable. 672 * 673 * @param bimap the bimap for which an unmodifiable view is to be returned 674 * @return an unmodifiable view of the specified bimap 675 */ 676 public static <K, V> BiMap<K, V> unmodifiableBiMap( 677 BiMap<? extends K, ? extends V> bimap) { 678 return new UnmodifiableBiMap<K, V>(bimap, null); 679 } 680 681 /** @see Maps#unmodifiableBiMap(BiMap) */ 682 private static class UnmodifiableBiMap<K, V> 683 extends ForwardingMap<K, V> implements BiMap<K, V>, Serializable { 684 final Map<K, V> unmodifiableMap; 685 final BiMap<? extends K, ? extends V> delegate; 686 transient BiMap<V, K> inverse; 687 transient Set<V> values; 688 689 UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate, 690 @Nullable BiMap<V, K> inverse) { 691 unmodifiableMap = Collections.unmodifiableMap(delegate); 692 this.delegate = delegate; 693 this.inverse = inverse; 694 } 695 696 @Override protected Map<K, V> delegate() { 697 return unmodifiableMap; 698 } 699 700 @Override 701 public V forcePut(K key, V value) { 702 throw new UnsupportedOperationException(); 703 } 704 705 @Override 706 public BiMap<V, K> inverse() { 707 BiMap<V, K> result = inverse; 708 return (result == null) 709 ? inverse = new UnmodifiableBiMap<V, K>(delegate.inverse(), this) 710 : result; 711 } 712 713 @Override public Set<V> values() { 714 Set<V> result = values; 715 return (result == null) 716 ? values = Collections.unmodifiableSet(delegate.values()) 717 : result; 718 } 719 720 private static final long serialVersionUID = 0; 721 } 722 723 /** 724 * Returns a view of a map where each value is transformed by a function. All 725 * other properties of the map, such as iteration order, are left intact. For 726 * example, the code: <pre> {@code 727 * 728 * Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9); 729 * Function<Integer, Double> sqrt = 730 * new Function<Integer, Double>() { 731 * public Double apply(Integer in) { 732 * return Math.sqrt((int) in); 733 * } 734 * }; 735 * Map<String, Double> transformed = Maps.transformValues(map, sqrt); 736 * System.out.println(transformed);}</pre> 737 * 738 * ... prints {@code {a=2.0, b=3.0}}. 739 * 740 * <p>Changes in the underlying map are reflected in this view. Conversely, 741 * this view supports removal operations, and these are reflected in the 742 * underlying map. 743 * 744 * <p>It's acceptable for the underlying map to contain null keys, and even 745 * null values provided that the function is capable of accepting null input. 746 * The transformed map might contain null values, if the function sometimes 747 * gives a null result. 748 * 749 * <p>The returned map is not thread-safe or serializable, even if the 750 * underlying map is. 751 * 752 * <p>The function is applied lazily, invoked when needed. This is necessary 753 * for the returned map to be a view, but it means that the function will be 754 * applied many times for bulk operations like {@link Map#containsValue} and 755 * {@code Map.toString()}. For this to perform well, {@code function} should 756 * be fast. To avoid lazy evaluation when the returned map doesn't need to be 757 * a view, copy the returned map into a new map of your choosing. 758 */ 759 public static <K, V1, V2> Map<K, V2> transformValues( 760 Map<K, V1> fromMap, final Function<? super V1, V2> function) { 761 checkNotNull(function); 762 EntryTransformer<K, V1, V2> transformer = 763 new EntryTransformer<K, V1, V2>() { 764 @Override 765 public V2 transformEntry(K key, V1 value) { 766 return function.apply(value); 767 } 768 }; 769 return transformEntries(fromMap, transformer); 770 } 771 772 /** 773 * Returns a view of a map whose values are derived from the original map's 774 * entries. In contrast to {@link #transformValues}, this method's 775 * entry-transformation logic may depend on the key as well as the value. 776 * 777 * <p>All other properties of the transformed map, such as iteration order, 778 * are left intact. For example, the code: <pre> {@code 779 * 780 * Map<String, Boolean> options = 781 * ImmutableMap.of("verbose", true, "sort", false); 782 * EntryTransformer<String, Boolean, String> flagPrefixer = 783 * new EntryTransformer<String, Boolean, String>() { 784 * public String transformEntry(String key, Boolean value) { 785 * return value ? key : "no" + key; 786 * } 787 * }; 788 * Map<String, String> transformed = 789 * Maps.transformEntries(options, flagPrefixer); 790 * System.out.println(transformed);}</pre> 791 * 792 * ... prints {@code {verbose=verbose, sort=nosort}}. 793 * 794 * <p>Changes in the underlying map are reflected in this view. Conversely, 795 * this view supports removal operations, and these are reflected in the 796 * underlying map. 797 * 798 * <p>It's acceptable for the underlying map to contain null keys and null 799 * values provided that the transformer is capable of accepting null inputs. 800 * The transformed map might contain null values if the transformer sometimes 801 * gives a null result. 802 * 803 * <p>The returned map is not thread-safe or serializable, even if the 804 * underlying map is. 805 * 806 * <p>The transformer is applied lazily, invoked when needed. This is 807 * necessary for the returned map to be a view, but it means that the 808 * transformer will be applied many times for bulk operations like {@link 809 * Map#containsValue} and {@link Object#toString}. For this to perform well, 810 * {@code transformer} should be fast. To avoid lazy evaluation when the 811 * returned map doesn't need to be a view, copy the returned map into a new 812 * map of your choosing. 813 * 814 * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 815 * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 816 * that {@code k2} is also of type {@code K}. Using an {@code 817 * EntryTransformer} key type for which this may not hold, such as {@code 818 * ArrayList}, may risk a {@code ClassCastException} when calling methods on 819 * the transformed map. 820 * 821 * @since 7 822 */ 823 @Beta 824 public static <K, V1, V2> Map<K, V2> transformEntries( 825 Map<K, V1> fromMap, 826 EntryTransformer<? super K, ? super V1, V2> transformer) { 827 return new TransformedEntriesMap<K, V1, V2>(fromMap, transformer); 828 } 829 830 /** 831 * A transformation of the value of a key-value pair, using both key and value 832 * as inputs. To apply the transformation to a map, use 833 * {@link Maps#transformEntries(Map, EntryTransformer)}. 834 * 835 * @param <K> the key type of the input and output entries 836 * @param <V1> the value type of the input entry 837 * @param <V2> the value type of the output entry 838 * @since 7 839 */ 840 @Beta 841 public interface EntryTransformer<K, V1, V2> { 842 /** 843 * Determines an output value based on a key-value pair. This method is 844 * <i>generally expected</i>, but not absolutely required, to have the 845 * following properties: 846 * 847 * <ul> 848 * <li>Its execution does not cause any observable side effects. 849 * <li>The computation is <i>consistent with equals</i>; that is, 850 * {@link Objects#equal Objects.equal}{@code (k1, k2) &&} 851 * {@link Objects#equal}{@code (v1, v2)} implies that {@code 852 * Objects.equal(transformer.transform(k1, v1), 853 * transformer.transform(k2, v2))}. 854 * </ul> 855 * 856 * @throws NullPointerException if the key or value is null and this 857 * transformer does not accept null arguments 858 */ 859 V2 transformEntry(@Nullable K key, @Nullable V1 value); 860 } 861 862 static class TransformedEntriesMap<K, V1, V2> 863 extends AbstractMap<K, V2> { 864 final Map<K, V1> fromMap; 865 final EntryTransformer<? super K, ? super V1, V2> transformer; 866 867 TransformedEntriesMap( 868 Map<K, V1> fromMap, 869 EntryTransformer<? super K, ? super V1, V2> transformer) { 870 this.fromMap = checkNotNull(fromMap); 871 this.transformer = checkNotNull(transformer); 872 } 873 874 @Override public int size() { 875 return fromMap.size(); 876 } 877 878 @Override public boolean containsKey(Object key) { 879 return fromMap.containsKey(key); 880 } 881 882 // safe as long as the user followed the <b>Warning</b> in the javadoc 883 @SuppressWarnings("unchecked") 884 @Override public V2 get(Object key) { 885 V1 value = fromMap.get(key); 886 return (value != null || fromMap.containsKey(key)) 887 ? transformer.transformEntry((K) key, value) 888 : null; 889 } 890 891 // safe as long as the user followed the <b>Warning</b> in the javadoc 892 @SuppressWarnings("unchecked") 893 @Override public V2 remove(Object key) { 894 return fromMap.containsKey(key) 895 ? transformer.transformEntry((K) key, fromMap.remove(key)) 896 : null; 897 } 898 899 @Override public void clear() { 900 fromMap.clear(); 901 } 902 903 EntrySet entrySet; 904 905 @Override public Set<Entry<K, V2>> entrySet() { 906 EntrySet result = entrySet; 907 if (result == null) { 908 entrySet = result = new EntrySet(); 909 } 910 return result; 911 } 912 913 class EntrySet extends AbstractSet<Entry<K, V2>> { 914 @Override public int size() { 915 return TransformedEntriesMap.this.size(); 916 } 917 918 @Override public Iterator<Entry<K, V2>> iterator() { 919 final Iterator<Entry<K, V1>> mapIterator = 920 fromMap.entrySet().iterator(); 921 922 return new Iterator<Entry<K, V2>>() { 923 @Override 924 public boolean hasNext() { 925 return mapIterator.hasNext(); 926 } 927 928 @Override 929 public Entry<K, V2> next() { 930 final Entry<K, V1> entry = mapIterator.next(); 931 return new AbstractMapEntry<K, V2>() { 932 @Override public K getKey() { 933 return entry.getKey(); 934 } 935 936 @Override public V2 getValue() { 937 return transformer.transformEntry( 938 entry.getKey(), entry.getValue()); 939 } 940 }; 941 } 942 943 @Override 944 public void remove() { 945 mapIterator.remove(); 946 } 947 }; 948 } 949 950 @Override public void clear() { 951 fromMap.clear(); 952 } 953 954 @Override public boolean contains(Object o) { 955 if (!(o instanceof Entry)) { 956 return false; 957 } 958 Entry<?, ?> entry = (Entry<?, ?>) o; 959 Object entryKey = entry.getKey(); 960 Object entryValue = entry.getValue(); 961 V2 mapValue = TransformedEntriesMap.this.get(entryKey); 962 if (mapValue != null) { 963 return mapValue.equals(entryValue); 964 } 965 return entryValue == null && containsKey(entryKey); 966 } 967 968 @Override public boolean remove(Object o) { 969 if (contains(o)) { 970 Entry<?, ?> entry = (Entry<?, ?>) o; 971 Object key = entry.getKey(); 972 fromMap.remove(key); 973 return true; 974 } 975 return false; 976 } 977 } 978 } 979 980 /** 981 * Returns a map containing the mappings in {@code unfiltered} whose keys 982 * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 983 * changes to one affect the other. 984 * 985 * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 986 * values()} views have iterators that don't support {@code remove()}, but all 987 * other methods are supported by the map and its views. When given a key that 988 * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()} 989 * methods throw an {@link IllegalArgumentException}. 990 * 991 * <p>When methods such as {@code removeAll()} and {@code clear()} are called 992 * on the filtered map or its views, only mappings whose keys satisfy the 993 * filter will be removed from the underlying map. 994 * 995 * <p>The returned map isn't threadsafe or serializable, even if {@code 996 * unfiltered} is. 997 * 998 * <p>Many of the filtered map's methods, such as {@code size()}, 999 * iterate across every key/value mapping in the underlying map and determine 1000 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1001 * faster to copy the filtered map and use the copy. 1002 * 1003 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with 1004 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 1005 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 1006 * inconsistent with equals. 1007 */ 1008 public static <K, V> Map<K, V> filterKeys( 1009 Map<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 1010 checkNotNull(keyPredicate); 1011 Predicate<Entry<K, V>> entryPredicate = 1012 new Predicate<Entry<K, V>>() { 1013 @Override 1014 public boolean apply(Entry<K, V> input) { 1015 return keyPredicate.apply(input.getKey()); 1016 } 1017 }; 1018 return (unfiltered instanceof AbstractFilteredMap) 1019 ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate) 1020 : new FilteredKeyMap<K, V>( 1021 checkNotNull(unfiltered), keyPredicate, entryPredicate); 1022 } 1023 1024 /** 1025 * Returns a map containing the mappings in {@code unfiltered} whose values 1026 * satisfy a predicate. The returned map is a live view of {@code unfiltered}; 1027 * changes to one affect the other. 1028 * 1029 * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 1030 * values()} views have iterators that don't support {@code remove()}, but all 1031 * other methods are supported by the map and its views. When given a value 1032 * that doesn't satisfy the predicate, the map's {@code put()}, {@code 1033 * putAll()}, and {@link Entry#setValue} methods throw an {@link 1034 * IllegalArgumentException}. 1035 * 1036 * <p>When methods such as {@code removeAll()} and {@code clear()} are called 1037 * on the filtered map or its views, only mappings whose values satisfy the 1038 * filter will be removed from the underlying map. 1039 * 1040 * <p>The returned map isn't threadsafe or serializable, even if {@code 1041 * unfiltered} is. 1042 * 1043 * <p>Many of the filtered map's methods, such as {@code size()}, 1044 * iterate across every key/value mapping in the underlying map and determine 1045 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1046 * faster to copy the filtered map and use the copy. 1047 * 1048 * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 1049 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 1050 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 1051 * inconsistent with equals. 1052 */ 1053 public static <K, V> Map<K, V> filterValues( 1054 Map<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 1055 checkNotNull(valuePredicate); 1056 Predicate<Entry<K, V>> entryPredicate = 1057 new Predicate<Entry<K, V>>() { 1058 @Override 1059 public boolean apply(Entry<K, V> input) { 1060 return valuePredicate.apply(input.getValue()); 1061 } 1062 }; 1063 return filterEntries(unfiltered, entryPredicate); 1064 } 1065 1066 /** 1067 * Returns a map containing the mappings in {@code unfiltered} that satisfy a 1068 * predicate. The returned map is a live view of {@code unfiltered}; changes 1069 * to one affect the other. 1070 * 1071 * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code 1072 * values()} views have iterators that don't support {@code remove()}, but all 1073 * other methods are supported by the map and its views. When given a 1074 * key/value pair that doesn't satisfy the predicate, the map's {@code put()} 1075 * and {@code putAll()} methods throw an {@link IllegalArgumentException}. 1076 * Similarly, the map's entries have a {@link Entry#setValue} method that 1077 * throws an {@link IllegalArgumentException} when the existing key and the 1078 * provided value don't satisfy the predicate. 1079 * 1080 * <p>When methods such as {@code removeAll()} and {@code clear()} are called 1081 * on the filtered map or its views, only mappings that satisfy the filter 1082 * will be removed from the underlying map. 1083 * 1084 * <p>The returned map isn't threadsafe or serializable, even if {@code 1085 * unfiltered} is. 1086 * 1087 * <p>Many of the filtered map's methods, such as {@code size()}, 1088 * iterate across every key/value mapping in the underlying map and determine 1089 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1090 * faster to copy the filtered map and use the copy. 1091 * 1092 * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 1093 * equals</i>, as documented at {@link Predicate#apply}. 1094 */ 1095 public static <K, V> Map<K, V> filterEntries( 1096 Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 1097 checkNotNull(entryPredicate); 1098 return (unfiltered instanceof AbstractFilteredMap) 1099 ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate) 1100 : new FilteredEntryMap<K, V>(checkNotNull(unfiltered), entryPredicate); 1101 } 1102 1103 /** 1104 * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when 1105 * filtering a filtered map. 1106 */ 1107 private static <K, V> Map<K, V> filterFiltered(AbstractFilteredMap<K, V> map, 1108 Predicate<? super Entry<K, V>> entryPredicate) { 1109 Predicate<Entry<K, V>> predicate = 1110 Predicates.and(map.predicate, entryPredicate); 1111 return new FilteredEntryMap<K, V>(map.unfiltered, predicate); 1112 } 1113 1114 private abstract static class AbstractFilteredMap<K, V> 1115 extends AbstractMap<K, V> { 1116 final Map<K, V> unfiltered; 1117 final Predicate<? super Entry<K, V>> predicate; 1118 1119 AbstractFilteredMap( 1120 Map<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) { 1121 this.unfiltered = unfiltered; 1122 this.predicate = predicate; 1123 } 1124 1125 boolean apply(Object key, V value) { 1126 // This method is called only when the key is in the map, implying that 1127 // key is a K. 1128 @SuppressWarnings("unchecked") 1129 K k = (K) key; 1130 return predicate.apply(Maps.immutableEntry(k, value)); 1131 } 1132 1133 @Override public V put(K key, V value) { 1134 checkArgument(apply(key, value)); 1135 return unfiltered.put(key, value); 1136 } 1137 1138 @Override public void putAll(Map<? extends K, ? extends V> map) { 1139 for (Entry<? extends K, ? extends V> entry : map.entrySet()) { 1140 checkArgument(apply(entry.getKey(), entry.getValue())); 1141 } 1142 unfiltered.putAll(map); 1143 } 1144 1145 @Override public boolean containsKey(Object key) { 1146 return unfiltered.containsKey(key) && apply(key, unfiltered.get(key)); 1147 } 1148 1149 @Override public V get(Object key) { 1150 V value = unfiltered.get(key); 1151 return ((value != null) && apply(key, value)) ? value : null; 1152 } 1153 1154 @Override public boolean isEmpty() { 1155 return entrySet().isEmpty(); 1156 } 1157 1158 @Override public V remove(Object key) { 1159 return containsKey(key) ? unfiltered.remove(key) : null; 1160 } 1161 1162 Collection<V> values; 1163 1164 @Override public Collection<V> values() { 1165 Collection<V> result = values; 1166 return (result == null) ? values = new Values() : result; 1167 } 1168 1169 class Values extends AbstractCollection<V> { 1170 @Override public Iterator<V> iterator() { 1171 final Iterator<Entry<K, V>> entryIterator = entrySet().iterator(); 1172 return new UnmodifiableIterator<V>() { 1173 @Override 1174 public boolean hasNext() { 1175 return entryIterator.hasNext(); 1176 } 1177 1178 @Override 1179 public V next() { 1180 return entryIterator.next().getValue(); 1181 } 1182 }; 1183 } 1184 1185 @Override public int size() { 1186 return entrySet().size(); 1187 } 1188 1189 @Override public void clear() { 1190 entrySet().clear(); 1191 } 1192 1193 @Override public boolean isEmpty() { 1194 return entrySet().isEmpty(); 1195 } 1196 1197 @Override public boolean remove(Object o) { 1198 Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 1199 while (iterator.hasNext()) { 1200 Entry<K, V> entry = iterator.next(); 1201 if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) { 1202 iterator.remove(); 1203 return true; 1204 } 1205 } 1206 return false; 1207 } 1208 1209 @Override public boolean removeAll(Collection<?> collection) { 1210 checkNotNull(collection); 1211 boolean changed = false; 1212 Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 1213 while (iterator.hasNext()) { 1214 Entry<K, V> entry = iterator.next(); 1215 if (collection.contains(entry.getValue()) && predicate.apply(entry)) { 1216 iterator.remove(); 1217 changed = true; 1218 } 1219 } 1220 return changed; 1221 } 1222 1223 @Override public boolean retainAll(Collection<?> collection) { 1224 checkNotNull(collection); 1225 boolean changed = false; 1226 Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 1227 while (iterator.hasNext()) { 1228 Entry<K, V> entry = iterator.next(); 1229 if (!collection.contains(entry.getValue()) 1230 && predicate.apply(entry)) { 1231 iterator.remove(); 1232 changed = true; 1233 } 1234 } 1235 return changed; 1236 } 1237 1238 @Override public Object[] toArray() { 1239 // creating an ArrayList so filtering happens once 1240 return Lists.newArrayList(iterator()).toArray(); 1241 } 1242 1243 @Override public <T> T[] toArray(T[] array) { 1244 return Lists.newArrayList(iterator()).toArray(array); 1245 } 1246 } 1247 } 1248 1249 private static class FilteredKeyMap<K, V> extends AbstractFilteredMap<K, V> { 1250 Predicate<? super K> keyPredicate; 1251 1252 FilteredKeyMap(Map<K, V> unfiltered, Predicate<? super K> keyPredicate, 1253 Predicate<Entry<K, V>> entryPredicate) { 1254 super(unfiltered, entryPredicate); 1255 this.keyPredicate = keyPredicate; 1256 } 1257 1258 Set<Entry<K, V>> entrySet; 1259 1260 @Override public Set<Entry<K, V>> entrySet() { 1261 Set<Entry<K, V>> result = entrySet; 1262 return (result == null) 1263 ? entrySet = Sets.filter(unfiltered.entrySet(), predicate) 1264 : result; 1265 } 1266 1267 Set<K> keySet; 1268 1269 @Override public Set<K> keySet() { 1270 Set<K> result = keySet; 1271 return (result == null) 1272 ? keySet = Sets.filter(unfiltered.keySet(), keyPredicate) 1273 : result; 1274 } 1275 1276 // The cast is called only when the key is in the unfiltered map, implying 1277 // that key is a K. 1278 @Override 1279 @SuppressWarnings("unchecked") 1280 public boolean containsKey(Object key) { 1281 return unfiltered.containsKey(key) && keyPredicate.apply((K) key); 1282 } 1283 } 1284 1285 static class FilteredEntryMap<K, V> extends AbstractFilteredMap<K, V> { 1286 /** 1287 * Entries in this set satisfy the predicate, but they don't validate the 1288 * input to {@code Entry.setValue()}. 1289 */ 1290 final Set<Entry<K, V>> filteredEntrySet; 1291 1292 FilteredEntryMap( 1293 Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 1294 super(unfiltered, entryPredicate); 1295 filteredEntrySet = Sets.filter(unfiltered.entrySet(), predicate); 1296 } 1297 1298 Set<Entry<K, V>> entrySet; 1299 1300 @Override public Set<Entry<K, V>> entrySet() { 1301 Set<Entry<K, V>> result = entrySet; 1302 return (result == null) ? entrySet = new EntrySet() : result; 1303 } 1304 1305 private class EntrySet extends ForwardingSet<Entry<K, V>> { 1306 @Override protected Set<Entry<K, V>> delegate() { 1307 return filteredEntrySet; 1308 } 1309 1310 @Override public Iterator<Entry<K, V>> iterator() { 1311 final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator(); 1312 return new UnmodifiableIterator<Entry<K, V>>() { 1313 @Override 1314 public boolean hasNext() { 1315 return iterator.hasNext(); 1316 } 1317 1318 @Override 1319 public Entry<K, V> next() { 1320 final Entry<K, V> entry = iterator.next(); 1321 return new ForwardingMapEntry<K, V>() { 1322 @Override protected Entry<K, V> delegate() { 1323 return entry; 1324 } 1325 1326 @Override public V setValue(V value) { 1327 checkArgument(apply(entry.getKey(), value)); 1328 return super.setValue(value); 1329 } 1330 }; 1331 } 1332 }; 1333 } 1334 } 1335 1336 Set<K> keySet; 1337 1338 @Override public Set<K> keySet() { 1339 Set<K> result = keySet; 1340 return (result == null) ? keySet = new KeySet() : result; 1341 } 1342 1343 private class KeySet extends AbstractSet<K> { 1344 @Override public Iterator<K> iterator() { 1345 final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator(); 1346 return new UnmodifiableIterator<K>() { 1347 @Override 1348 public boolean hasNext() { 1349 return iterator.hasNext(); 1350 } 1351 1352 @Override 1353 public K next() { 1354 return iterator.next().getKey(); 1355 } 1356 }; 1357 } 1358 1359 @Override public int size() { 1360 return filteredEntrySet.size(); 1361 } 1362 1363 @Override public void clear() { 1364 filteredEntrySet.clear(); 1365 } 1366 1367 @Override public boolean contains(Object o) { 1368 return containsKey(o); 1369 } 1370 1371 @Override public boolean remove(Object o) { 1372 if (containsKey(o)) { 1373 unfiltered.remove(o); 1374 return true; 1375 } 1376 return false; 1377 } 1378 1379 @Override public boolean removeAll(Collection<?> collection) { 1380 checkNotNull(collection); // for GWT 1381 boolean changed = false; 1382 for (Object obj : collection) { 1383 changed |= remove(obj); 1384 } 1385 return changed; 1386 } 1387 1388 @Override public boolean retainAll(Collection<?> collection) { 1389 checkNotNull(collection); // for GWT 1390 boolean changed = false; 1391 Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator(); 1392 while (iterator.hasNext()) { 1393 Entry<K, V> entry = iterator.next(); 1394 if (!collection.contains(entry.getKey()) && predicate.apply(entry)) { 1395 iterator.remove(); 1396 changed = true; 1397 } 1398 } 1399 return changed; 1400 } 1401 1402 @Override public Object[] toArray() { 1403 // creating an ArrayList so filtering happens once 1404 return Lists.newArrayList(iterator()).toArray(); 1405 } 1406 1407 @Override public <T> T[] toArray(T[] array) { 1408 return Lists.newArrayList(iterator()).toArray(array); 1409 } 1410 } 1411 } 1412 1413 /** 1414 * {@code AbstractMap} extension that implements {@link #isEmpty()} as {@code 1415 * entrySet().isEmpty()} instead of {@code size() == 0} to speed up 1416 * implementations where {@code size()} is O(n), and it delegates the {@code 1417 * isEmpty()} methods of its key set and value collection to this 1418 * implementation. 1419 */ 1420 @GwtCompatible 1421 abstract static class ImprovedAbstractMap<K, V> extends AbstractMap<K, V> { 1422 /** 1423 * Creates the entry set to be returned by {@link #entrySet()}. This method 1424 * is invoked at most once on a given map, at the time when {@code entrySet} 1425 * is first called. 1426 */ 1427 protected abstract Set<Entry<K, V>> createEntrySet(); 1428 1429 private Set<Entry<K, V>> entrySet; 1430 1431 @Override public Set<Entry<K, V>> entrySet() { 1432 Set<Entry<K, V>> result = entrySet; 1433 if (result == null) { 1434 entrySet = result = createEntrySet(); 1435 } 1436 return result; 1437 } 1438 1439 private Set<K> keySet; 1440 1441 @Override public Set<K> keySet() { 1442 Set<K> result = keySet; 1443 if (result == null) { 1444 final Set<K> delegate = super.keySet(); 1445 keySet = result = new ForwardingSet<K>() { 1446 @Override protected Set<K> delegate() { 1447 return delegate; 1448 } 1449 1450 @Override public boolean isEmpty() { 1451 return ImprovedAbstractMap.this.isEmpty(); 1452 } 1453 1454 @Override public boolean remove(Object object) { 1455 if (contains(object)) { 1456 ImprovedAbstractMap.this.remove(object); 1457 return true; 1458 } 1459 return false; 1460 } 1461 }; 1462 } 1463 return result; 1464 } 1465 1466 private Collection<V> values; 1467 1468 @Override public Collection<V> values() { 1469 Collection<V> result = values; 1470 if (result == null) { 1471 final Collection<V> delegate = super.values(); 1472 values = result = new ForwardingCollection<V>() { 1473 @Override protected Collection<V> delegate() { 1474 return delegate; 1475 } 1476 1477 @Override public boolean isEmpty() { 1478 return ImprovedAbstractMap.this.isEmpty(); 1479 } 1480 }; 1481 } 1482 return result; 1483 } 1484 1485 /** 1486 * Returns {@code true} if this map contains no key-value mappings. 1487 * 1488 * <p>The implementation returns {@code entrySet().isEmpty()}. 1489 * 1490 * @return {@code true} if this map contains no key-value mappings 1491 */ 1492 @Override public boolean isEmpty() { 1493 return entrySet().isEmpty(); 1494 } 1495 } 1496 1497 static final MapJoiner STANDARD_JOINER = 1498 Collections2.STANDARD_JOINER.withKeyValueSeparator("="); 1499 1500 /** 1501 * Delegates to {@link Map#get}. Returns {@code null} on {@code 1502 * ClassCastException}. 1503 */ 1504 static <V> V safeGet(Map<?, V> map, Object key) { 1505 try { 1506 return map.get(key); 1507 } catch (ClassCastException e) { 1508 return null; 1509 } 1510 } 1511 1512 /** 1513 * Delegates to {@link Map#containsKey}. Returns {@code false} on {@code 1514 * ClassCastException} 1515 */ 1516 static boolean safeContainsKey(Map<?, ?> map, Object key) { 1517 try { 1518 return map.containsKey(key); 1519 } catch (ClassCastException e) { 1520 return false; 1521 } 1522 } 1523 1524 /** 1525 * An implementation of {@link Map#entrySet}. 1526 */ 1527 static <K, V> Set<Entry<K, V>> entrySetImpl( 1528 Map<K, V> map, Supplier<Iterator<Entry<K, V>>> entryIteratorSupplier) { 1529 return new EntrySetImpl<K, V>(map, entryIteratorSupplier); 1530 } 1531 1532 private static class EntrySetImpl<K, V> extends AbstractSet<Entry<K, V>> { 1533 private final Map<K, V> map; 1534 private final Supplier<Iterator<Entry<K, V>>> entryIteratorSupplier; 1535 1536 EntrySetImpl( 1537 Map<K, V> map, Supplier<Iterator<Entry<K, V>>> entryIteratorSupplier) { 1538 this.map = checkNotNull(map); 1539 this.entryIteratorSupplier = checkNotNull(entryIteratorSupplier); 1540 } 1541 1542 @Override public Iterator<Entry<K, V>> iterator() { 1543 return entryIteratorSupplier.get(); 1544 } 1545 1546 @Override public int size() { 1547 return map.size(); 1548 } 1549 1550 @Override public void clear() { 1551 map.clear(); 1552 } 1553 1554 @Override public boolean contains(Object o) { 1555 if (o instanceof Entry) { 1556 Entry<?, ?> entry = (Entry<?, ?>) o; 1557 Object key = entry.getKey(); 1558 if (map.containsKey(key)) { 1559 V value = map.get(entry.getKey()); 1560 return Objects.equal(value, entry.getValue()); 1561 } 1562 } 1563 return false; 1564 } 1565 1566 @Override public boolean isEmpty() { 1567 return map.isEmpty(); 1568 } 1569 1570 @Override public boolean remove(Object o) { 1571 if (contains(o)) { 1572 Entry<?, ?> entry = (Entry<?, ?>) o; 1573 map.remove(entry.getKey()); 1574 return true; 1575 } 1576 return false; 1577 } 1578 1579 @Override public int hashCode() { 1580 return map.hashCode(); 1581 } 1582 } 1583 1584 /** 1585 * Implements {@code Collection.contains} safely for forwarding collections of 1586 * map entries. If {@code o} is an instance of {@code Map.Entry}, it is 1587 * wrapped using {@link #unmodifiableEntry} to protect against a possible 1588 * nefarious equals method. 1589 * 1590 * <p>Note that {@code c} is the backing (delegate) collection, rather than 1591 * the forwarding collection. 1592 * 1593 * @param c the delegate (unwrapped) collection of map entries 1594 * @param o the object that might be contained in {@code c} 1595 * @return {@code true} if {@code c} contains {@code o} 1596 */ 1597 static <K, V> boolean containsEntryImpl(Collection<Entry<K, V>> c, Object o) { 1598 if (!(o instanceof Entry)) { 1599 return false; 1600 } 1601 return c.contains(unmodifiableEntry((Entry<?, ?>) o)); 1602 } 1603 1604 /** 1605 * Implements {@code Collection.remove} safely for forwarding collections of 1606 * map entries. If {@code o} is an instance of {@code Map.Entry}, it is 1607 * wrapped using {@link #unmodifiableEntry} to protect against a possible 1608 * nefarious equals method. 1609 * 1610 * <p>Note that {@code c} is backing (delegate) collection, rather than the 1611 * forwarding collection. 1612 * 1613 * @param c the delegate (unwrapped) collection of map entries 1614 * @param o the object to remove from {@code c} 1615 * @return {@code true} if {@code c} was changed 1616 */ 1617 static <K, V> boolean removeEntryImpl(Collection<Entry<K, V>> c, Object o) { 1618 if (!(o instanceof Entry)) { 1619 return false; 1620 } 1621 return c.remove(unmodifiableEntry((Entry<?, ?>) o)); 1622 } 1623 1624 /** 1625 * An implementation of {@link Map#equals}. 1626 */ 1627 static boolean equalsImpl(Map<?, ?> map, Object object) { 1628 if (map == object) { 1629 return true; 1630 } 1631 if (object instanceof Map) { 1632 Map<?, ?> o = (Map<?, ?>) object; 1633 return map.entrySet().equals(o.entrySet()); 1634 } 1635 return false; 1636 } 1637 1638 /** 1639 * An implementation of {@link Map#hashCode}. 1640 */ 1641 static int hashCodeImpl(Map<?, ?> map) { 1642 return Sets.hashCodeImpl(map.entrySet()); 1643 } 1644 1645 /** 1646 * An implementation of {@link Map#toString}. 1647 */ 1648 static String toStringImpl(Map<?, ?> map) { 1649 StringBuilder sb 1650 = Collections2.newStringBuilderForCollection(map.size()).append('{'); 1651 STANDARD_JOINER.appendTo(sb, map); 1652 return sb.append('}').toString(); 1653 } 1654 1655 /** 1656 * An implementation of {@link Map#putAll}. 1657 */ 1658 static <K, V> void putAllImpl( 1659 Map<K, V> self, Map<? extends K, ? extends V> map) { 1660 for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { 1661 self.put(entry.getKey(), entry.getValue()); 1662 } 1663 } 1664 1665 /** 1666 * An implementation of {@link Map#keySet}. 1667 */ 1668 static <K, V> Set<K> keySetImpl(final Map<K, V> map) { 1669 return new AbstractMapWrapper<K, V>(map).keySet(); 1670 } 1671 1672 /** 1673 * An admittedly inefficient implementation of {@link Map#containsKey}. 1674 */ 1675 static boolean containsKeyImpl(Map<?, ?> map, @Nullable Object key) { 1676 for (Entry<?, ?> entry : map.entrySet()) { 1677 if (Objects.equal(entry.getKey(), key)) { 1678 return true; 1679 } 1680 } 1681 return false; 1682 } 1683 1684 /** 1685 * An implementation of {@link Map#values}. 1686 */ 1687 static <K, V> Collection<V> valuesImpl(Map<K, V> map) { 1688 return new AbstractMapWrapper<K, V>(map).values(); 1689 } 1690 1691 /** 1692 * An implementation of {@link Map#containsValue}. 1693 */ 1694 static boolean containsValueImpl(Map<?, ?> map, @Nullable Object value) { 1695 for (Entry<?, ?> entry : map.entrySet()) { 1696 if (Objects.equal(entry.getValue(), value)) { 1697 return true; 1698 } 1699 } 1700 return false; 1701 } 1702 1703 /** 1704 * A wrapper on a map that supplies the {@code ImprovedAbstractMap} 1705 * implementations of {@code keySet()} and {@code values()}. 1706 */ 1707 private static final class AbstractMapWrapper<K, V> 1708 extends ImprovedAbstractMap<K, V>{ 1709 private final Map<K, V> map; 1710 1711 AbstractMapWrapper(Map<K, V> map) { 1712 this.map = checkNotNull(map); 1713 } 1714 1715 @Override public void clear() { 1716 map.clear(); 1717 } 1718 1719 @Override public boolean containsKey(Object key) { 1720 return map.containsKey(key); 1721 } 1722 1723 @Override public V remove(Object key) { 1724 return map.remove(key); 1725 } 1726 1727 @Override public boolean containsValue(Object value) { 1728 return map.containsValue(value); 1729 } 1730 1731 @Override protected Set<Entry<K, V>> createEntrySet() { 1732 return map.entrySet(); 1733 } 1734 1735 @Override public boolean isEmpty() { 1736 return map.isEmpty(); 1737 } 1738 1739 @Override public int size() { 1740 return map.size(); 1741 } 1742 } 1743 }