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