001/* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.collect; 018 019import static com.google.common.base.Preconditions.checkNotNull; 020import static com.google.common.collect.CollectPreconditions.checkNonnegative; 021import static com.google.common.collect.CollectPreconditions.checkRemove; 022 023import com.google.common.annotations.Beta; 024import com.google.common.annotations.GwtCompatible; 025import com.google.common.annotations.GwtIncompatible; 026import com.google.common.base.Function; 027import com.google.common.base.Predicate; 028import com.google.common.base.Predicates; 029import com.google.common.base.Supplier; 030import com.google.common.collect.Maps.EntryTransformer; 031import com.google.j2objc.annotations.Weak; 032import com.google.j2objc.annotations.WeakOuter; 033 034import java.io.IOException; 035import java.io.ObjectInputStream; 036import java.io.ObjectOutputStream; 037import java.io.Serializable; 038import java.util.AbstractCollection; 039import java.util.Collection; 040import java.util.Collections; 041import java.util.Comparator; 042import java.util.HashSet; 043import java.util.Iterator; 044import java.util.List; 045import java.util.Map; 046import java.util.Map.Entry; 047import java.util.NoSuchElementException; 048import java.util.Set; 049import java.util.SortedSet; 050 051import javax.annotation.CheckReturnValue; 052import javax.annotation.Nullable; 053 054/** 055 * Provides static methods acting on or generating a {@code Multimap}. 056 * 057 * <p>See the Guava User Guide article on <a href= 058 * "https://github.com/google/guava/wiki/CollectionUtilitiesExplained#multimaps"> 059 * {@code Multimaps}</a>. 060 * 061 * @author Jared Levy 062 * @author Robert Konigsberg 063 * @author Mike Bostock 064 * @author Louis Wasserman 065 * @since 2.0 066 */ 067@GwtCompatible(emulated = true) 068public final class Multimaps { 069 private Multimaps() {} 070 071 /** 072 * Creates a new {@code Multimap} backed by {@code map}, whose internal value 073 * collections are generated by {@code factory}. 074 * 075 * <b>Warning: do not use</b> this method when the collections returned by 076 * {@code factory} implement either {@link List} or {@code Set}! Use the more 077 * specific method {@link #newListMultimap}, {@link #newSetMultimap} or {@link 078 * #newSortedSetMultimap} instead, to avoid very surprising behavior from 079 * {@link Multimap#equals}. 080 * 081 * <p>The {@code factory}-generated and {@code map} classes determine the 082 * multimap iteration order. They also specify the behavior of the 083 * {@code equals}, {@code hashCode}, and {@code toString} methods for the 084 * multimap and its returned views. However, the multimap's {@code get} 085 * method returns instances of a different class than {@code factory.get()} 086 * does. 087 * 088 * <p>The multimap is serializable if {@code map}, {@code factory}, the 089 * collections generated by {@code factory}, and the multimap contents are all 090 * serializable. 091 * 092 * <p>The multimap is not threadsafe when any concurrent operations update the 093 * multimap, even if {@code map} and the instances generated by 094 * {@code factory} are. Concurrent read operations will work correctly. To 095 * allow concurrent update operations, wrap the multimap with a call to 096 * {@link #synchronizedMultimap}. 097 * 098 * <p>Call this method only when the simpler methods 099 * {@link ArrayListMultimap#create()}, {@link HashMultimap#create()}, 100 * {@link LinkedHashMultimap#create()}, {@link LinkedListMultimap#create()}, 101 * {@link TreeMultimap#create()}, and 102 * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. 103 * 104 * <p>Note: the multimap assumes complete ownership over of {@code map} and 105 * the collections returned by {@code factory}. Those objects should not be 106 * manually updated and they should not use soft, weak, or phantom references. 107 * 108 * @param map place to store the mapping from each key to its corresponding 109 * values 110 * @param factory supplier of new, empty collections that will each hold all 111 * values for a given key 112 * @throws IllegalArgumentException if {@code map} is not empty 113 */ 114 public static <K, V> Multimap<K, V> newMultimap(Map<K, Collection<V>> map, 115 final Supplier<? extends Collection<V>> factory) { 116 return new CustomMultimap<K, V>(map, factory); 117 } 118 119 private static class CustomMultimap<K, V> extends AbstractMapBasedMultimap<K, V> { 120 transient Supplier<? extends Collection<V>> factory; 121 122 CustomMultimap(Map<K, Collection<V>> map, 123 Supplier<? extends Collection<V>> factory) { 124 super(map); 125 this.factory = checkNotNull(factory); 126 } 127 128 @Override protected Collection<V> createCollection() { 129 return factory.get(); 130 } 131 132 // can't use Serialization writeMultimap and populateMultimap methods since 133 // there's no way to generate the empty backing map. 134 135 /** @serialData the factory and the backing map */ 136 @GwtIncompatible("java.io.ObjectOutputStream") 137 private void writeObject(ObjectOutputStream stream) throws IOException { 138 stream.defaultWriteObject(); 139 stream.writeObject(factory); 140 stream.writeObject(backingMap()); 141 } 142 143 @GwtIncompatible("java.io.ObjectInputStream") 144 @SuppressWarnings("unchecked") // reading data stored by writeObject 145 private void readObject(ObjectInputStream stream) 146 throws IOException, ClassNotFoundException { 147 stream.defaultReadObject(); 148 factory = (Supplier<? extends Collection<V>>) stream.readObject(); 149 Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 150 setMap(map); 151 } 152 153 @GwtIncompatible("java serialization not supported") 154 private static final long serialVersionUID = 0; 155 } 156 157 /** 158 * Creates a new {@code ListMultimap} that uses the provided map and factory. 159 * It can generate a multimap based on arbitrary {@link Map} and {@link List} 160 * classes. 161 * 162 * <p>The {@code factory}-generated and {@code map} classes determine the 163 * multimap iteration order. They also specify the behavior of the 164 * {@code equals}, {@code hashCode}, and {@code toString} methods for the 165 * multimap and its returned views. The multimap's {@code get}, {@code 166 * removeAll}, and {@code replaceValues} methods return {@code RandomAccess} 167 * lists if the factory does. However, the multimap's {@code get} method 168 * returns instances of a different class than does {@code factory.get()}. 169 * 170 * <p>The multimap is serializable if {@code map}, {@code factory}, the 171 * lists generated by {@code factory}, and the multimap contents are all 172 * serializable. 173 * 174 * <p>The multimap is not threadsafe when any concurrent operations update the 175 * multimap, even if {@code map} and the instances generated by 176 * {@code factory} are. Concurrent read operations will work correctly. To 177 * allow concurrent update operations, wrap the multimap with a call to 178 * {@link #synchronizedListMultimap}. 179 * 180 * <p>Call this method only when the simpler methods 181 * {@link ArrayListMultimap#create()} and {@link LinkedListMultimap#create()} 182 * won't suffice. 183 * 184 * <p>Note: the multimap assumes complete ownership over of {@code map} and 185 * the lists returned by {@code factory}. Those objects should not be manually 186 * updated, they should be empty when provided, and they should not use soft, 187 * weak, or phantom references. 188 * 189 * @param map place to store the mapping from each key to its corresponding 190 * values 191 * @param factory supplier of new, empty lists that will each hold all values 192 * for a given key 193 * @throws IllegalArgumentException if {@code map} is not empty 194 */ 195 public static <K, V> ListMultimap<K, V> newListMultimap( 196 Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) { 197 return new CustomListMultimap<K, V>(map, factory); 198 } 199 200 private static class CustomListMultimap<K, V> 201 extends AbstractListMultimap<K, V> { 202 transient Supplier<? extends List<V>> factory; 203 204 CustomListMultimap(Map<K, Collection<V>> map, 205 Supplier<? extends List<V>> factory) { 206 super(map); 207 this.factory = checkNotNull(factory); 208 } 209 210 @Override protected List<V> createCollection() { 211 return factory.get(); 212 } 213 214 /** @serialData the factory and the backing map */ 215 @GwtIncompatible("java.io.ObjectOutputStream") 216 private void writeObject(ObjectOutputStream stream) throws IOException { 217 stream.defaultWriteObject(); 218 stream.writeObject(factory); 219 stream.writeObject(backingMap()); 220 } 221 222 @GwtIncompatible("java.io.ObjectInputStream") 223 @SuppressWarnings("unchecked") // reading data stored by writeObject 224 private void readObject(ObjectInputStream stream) 225 throws IOException, ClassNotFoundException { 226 stream.defaultReadObject(); 227 factory = (Supplier<? extends List<V>>) stream.readObject(); 228 Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 229 setMap(map); 230 } 231 232 @GwtIncompatible("java serialization not supported") 233 private static final long serialVersionUID = 0; 234 } 235 236 /** 237 * Creates a new {@code SetMultimap} that uses the provided map and factory. 238 * It can generate a multimap based on arbitrary {@link Map} and {@link Set} 239 * classes. 240 * 241 * <p>The {@code factory}-generated and {@code map} classes determine the 242 * multimap iteration order. They also specify the behavior of the 243 * {@code equals}, {@code hashCode}, and {@code toString} methods for the 244 * multimap and its returned views. However, the multimap's {@code get} 245 * method returns instances of a different class than {@code factory.get()} 246 * does. 247 * 248 * <p>The multimap is serializable if {@code map}, {@code factory}, the 249 * sets generated by {@code factory}, and the multimap contents are all 250 * serializable. 251 * 252 * <p>The multimap is not threadsafe when any concurrent operations update the 253 * multimap, even if {@code map} and the instances generated by 254 * {@code factory} are. Concurrent read operations will work correctly. To 255 * allow concurrent update operations, wrap the multimap with a call to 256 * {@link #synchronizedSetMultimap}. 257 * 258 * <p>Call this method only when the simpler methods 259 * {@link HashMultimap#create()}, {@link LinkedHashMultimap#create()}, 260 * {@link TreeMultimap#create()}, and 261 * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. 262 * 263 * <p>Note: the multimap assumes complete ownership over of {@code map} and 264 * the sets returned by {@code factory}. Those objects should not be manually 265 * updated and they should not use soft, weak, or phantom references. 266 * 267 * @param map place to store the mapping from each key to its corresponding 268 * values 269 * @param factory supplier of new, empty sets that will each hold all values 270 * for a given key 271 * @throws IllegalArgumentException if {@code map} is not empty 272 */ 273 public static <K, V> SetMultimap<K, V> newSetMultimap( 274 Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) { 275 return new CustomSetMultimap<K, V>(map, factory); 276 } 277 278 private static class CustomSetMultimap<K, V> 279 extends AbstractSetMultimap<K, V> { 280 transient Supplier<? extends Set<V>> factory; 281 282 CustomSetMultimap(Map<K, Collection<V>> map, 283 Supplier<? extends Set<V>> factory) { 284 super(map); 285 this.factory = checkNotNull(factory); 286 } 287 288 @Override protected Set<V> createCollection() { 289 return factory.get(); 290 } 291 292 /** @serialData the factory and the backing map */ 293 @GwtIncompatible("java.io.ObjectOutputStream") 294 private void writeObject(ObjectOutputStream stream) throws IOException { 295 stream.defaultWriteObject(); 296 stream.writeObject(factory); 297 stream.writeObject(backingMap()); 298 } 299 300 @GwtIncompatible("java.io.ObjectInputStream") 301 @SuppressWarnings("unchecked") // reading data stored by writeObject 302 private void readObject(ObjectInputStream stream) 303 throws IOException, ClassNotFoundException { 304 stream.defaultReadObject(); 305 factory = (Supplier<? extends Set<V>>) stream.readObject(); 306 Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 307 setMap(map); 308 } 309 310 @GwtIncompatible("not needed in emulated source") 311 private static final long serialVersionUID = 0; 312 } 313 314 /** 315 * Creates a new {@code SortedSetMultimap} that uses the provided map and 316 * factory. It can generate a multimap based on arbitrary {@link Map} and 317 * {@link SortedSet} classes. 318 * 319 * <p>The {@code factory}-generated and {@code map} classes determine the 320 * multimap iteration order. They also specify the behavior of the 321 * {@code equals}, {@code hashCode}, and {@code toString} methods for the 322 * multimap and its returned views. However, the multimap's {@code get} 323 * method returns instances of a different class than {@code factory.get()} 324 * does. 325 * 326 * <p>The multimap is serializable if {@code map}, {@code factory}, the 327 * sets generated by {@code factory}, and the multimap contents are all 328 * serializable. 329 * 330 * <p>The multimap is not threadsafe when any concurrent operations update the 331 * multimap, even if {@code map} and the instances generated by 332 * {@code factory} are. Concurrent read operations will work correctly. To 333 * allow concurrent update operations, wrap the multimap with a call to 334 * {@link #synchronizedSortedSetMultimap}. 335 * 336 * <p>Call this method only when the simpler methods 337 * {@link TreeMultimap#create()} and 338 * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. 339 * 340 * <p>Note: the multimap assumes complete ownership over of {@code map} and 341 * the sets returned by {@code factory}. Those objects should not be manually 342 * updated and they should not use soft, weak, or phantom references. 343 * 344 * @param map place to store the mapping from each key to its corresponding 345 * values 346 * @param factory supplier of new, empty sorted sets that will each hold 347 * all values for a given key 348 * @throws IllegalArgumentException if {@code map} is not empty 349 */ 350 public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap( 351 Map<K, Collection<V>> map, 352 final Supplier<? extends SortedSet<V>> factory) { 353 return new CustomSortedSetMultimap<K, V>(map, factory); 354 } 355 356 private static class CustomSortedSetMultimap<K, V> 357 extends AbstractSortedSetMultimap<K, V> { 358 transient Supplier<? extends SortedSet<V>> factory; 359 transient Comparator<? super V> valueComparator; 360 361 CustomSortedSetMultimap(Map<K, Collection<V>> map, 362 Supplier<? extends SortedSet<V>> factory) { 363 super(map); 364 this.factory = checkNotNull(factory); 365 valueComparator = factory.get().comparator(); 366 } 367 368 @Override protected SortedSet<V> createCollection() { 369 return factory.get(); 370 } 371 372 @Override public Comparator<? super V> valueComparator() { 373 return valueComparator; 374 } 375 376 /** @serialData the factory and the backing map */ 377 @GwtIncompatible("java.io.ObjectOutputStream") 378 private void writeObject(ObjectOutputStream stream) throws IOException { 379 stream.defaultWriteObject(); 380 stream.writeObject(factory); 381 stream.writeObject(backingMap()); 382 } 383 384 @GwtIncompatible("java.io.ObjectInputStream") 385 @SuppressWarnings("unchecked") // reading data stored by writeObject 386 private void readObject(ObjectInputStream stream) 387 throws IOException, ClassNotFoundException { 388 stream.defaultReadObject(); 389 factory = (Supplier<? extends SortedSet<V>>) stream.readObject(); 390 valueComparator = factory.get().comparator(); 391 Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 392 setMap(map); 393 } 394 395 @GwtIncompatible("not needed in emulated source") 396 private static final long serialVersionUID = 0; 397 } 398 399 /** 400 * Copies each key-value mapping in {@code source} into {@code dest}, with 401 * its key and value reversed. 402 * 403 * <p>If {@code source} is an {@link ImmutableMultimap}, consider using 404 * {@link ImmutableMultimap#inverse} instead. 405 * 406 * @param source any multimap 407 * @param dest the multimap to copy into; usually empty 408 * @return {@code dest} 409 */ 410 public static <K, V, M extends Multimap<K, V>> M invertFrom( 411 Multimap<? extends V, ? extends K> source, M dest) { 412 checkNotNull(dest); 413 for (Map.Entry<? extends V, ? extends K> entry : source.entries()) { 414 dest.put(entry.getValue(), entry.getKey()); 415 } 416 return dest; 417 } 418 419 /** 420 * Returns a synchronized (thread-safe) multimap backed by the specified 421 * multimap. In order to guarantee serial access, it is critical that 422 * <b>all</b> access to the backing multimap is accomplished through the 423 * returned multimap. 424 * 425 * <p>It is imperative that the user manually synchronize on the returned 426 * multimap when accessing any of its collection views: <pre> {@code 427 * 428 * Multimap<K, V> multimap = Multimaps.synchronizedMultimap( 429 * HashMultimap.<K, V>create()); 430 * ... 431 * Collection<V> values = multimap.get(key); // Needn't be in synchronized block 432 * ... 433 * synchronized (multimap) { // Synchronizing on multimap, not values! 434 * Iterator<V> i = values.iterator(); // Must be in synchronized block 435 * while (i.hasNext()) { 436 * foo(i.next()); 437 * } 438 * }}</pre> 439 * 440 * <p>Failure to follow this advice may result in non-deterministic behavior. 441 * 442 * <p>Note that the generated multimap's {@link Multimap#removeAll} and 443 * {@link Multimap#replaceValues} methods return collections that aren't 444 * synchronized. 445 * 446 * <p>The returned multimap will be serializable if the specified multimap is 447 * serializable. 448 * 449 * @param multimap the multimap to be wrapped in a synchronized view 450 * @return a synchronized view of the specified multimap 451 */ 452 public static <K, V> Multimap<K, V> synchronizedMultimap( 453 Multimap<K, V> multimap) { 454 return Synchronized.multimap(multimap, null); 455 } 456 457 /** 458 * Returns an unmodifiable view of the specified multimap. Query operations on 459 * the returned multimap "read through" to the specified multimap, and 460 * attempts to modify the returned multimap, either directly or through the 461 * multimap's views, result in an {@code UnsupportedOperationException}. 462 * 463 * <p>Note that the generated multimap's {@link Multimap#removeAll} and 464 * {@link Multimap#replaceValues} methods return collections that are 465 * modifiable. 466 * 467 * <p>The returned multimap will be serializable if the specified multimap is 468 * serializable. 469 * 470 * @param delegate the multimap for which an unmodifiable view is to be 471 * returned 472 * @return an unmodifiable view of the specified multimap 473 */ 474 public static <K, V> Multimap<K, V> unmodifiableMultimap( 475 Multimap<K, V> delegate) { 476 if (delegate instanceof UnmodifiableMultimap || 477 delegate instanceof ImmutableMultimap) { 478 return delegate; 479 } 480 return new UnmodifiableMultimap<K, V>(delegate); 481 } 482 483 /** 484 * Simply returns its argument. 485 * 486 * @deprecated no need to use this 487 * @since 10.0 488 */ 489 @Deprecated public static <K, V> Multimap<K, V> unmodifiableMultimap( 490 ImmutableMultimap<K, V> delegate) { 491 return checkNotNull(delegate); 492 } 493 494 private static class UnmodifiableMultimap<K, V> 495 extends ForwardingMultimap<K, V> implements Serializable { 496 final Multimap<K, V> delegate; 497 transient Collection<Entry<K, V>> entries; 498 transient Multiset<K> keys; 499 transient Set<K> keySet; 500 transient Collection<V> values; 501 transient Map<K, Collection<V>> map; 502 503 UnmodifiableMultimap(final Multimap<K, V> delegate) { 504 this.delegate = checkNotNull(delegate); 505 } 506 507 @Override protected Multimap<K, V> delegate() { 508 return delegate; 509 } 510 511 @Override public void clear() { 512 throw new UnsupportedOperationException(); 513 } 514 515 @Override public Map<K, Collection<V>> asMap() { 516 Map<K, Collection<V>> result = map; 517 if (result == null) { 518 result = map = Collections.unmodifiableMap( 519 Maps.transformValues(delegate.asMap(), new Function<Collection<V>, Collection<V>>() { 520 @Override 521 public Collection<V> apply(Collection<V> collection) { 522 return unmodifiableValueCollection(collection); 523 } 524 })); 525 } 526 return result; 527 } 528 529 @Override public Collection<Entry<K, V>> entries() { 530 Collection<Entry<K, V>> result = entries; 531 if (result == null) { 532 entries = result = unmodifiableEntries(delegate.entries()); 533 } 534 return result; 535 } 536 537 @Override public Collection<V> get(K key) { 538 return unmodifiableValueCollection(delegate.get(key)); 539 } 540 541 @Override public Multiset<K> keys() { 542 Multiset<K> result = keys; 543 if (result == null) { 544 keys = result = Multisets.unmodifiableMultiset(delegate.keys()); 545 } 546 return result; 547 } 548 549 @Override public Set<K> keySet() { 550 Set<K> result = keySet; 551 if (result == null) { 552 keySet = result = Collections.unmodifiableSet(delegate.keySet()); 553 } 554 return result; 555 } 556 557 @Override public boolean put(K key, V value) { 558 throw new UnsupportedOperationException(); 559 } 560 561 @Override public boolean putAll(K key, Iterable<? extends V> values) { 562 throw new UnsupportedOperationException(); 563 } 564 565 @Override 566 public boolean putAll(Multimap<? extends K, ? extends V> multimap) { 567 throw new UnsupportedOperationException(); 568 } 569 570 @Override public boolean remove(Object key, Object value) { 571 throw new UnsupportedOperationException(); 572 } 573 574 @Override public Collection<V> removeAll(Object key) { 575 throw new UnsupportedOperationException(); 576 } 577 578 @Override public Collection<V> replaceValues( 579 K key, Iterable<? extends V> values) { 580 throw new UnsupportedOperationException(); 581 } 582 583 @Override public Collection<V> values() { 584 Collection<V> result = values; 585 if (result == null) { 586 values = result = Collections.unmodifiableCollection(delegate.values()); 587 } 588 return result; 589 } 590 591 private static final long serialVersionUID = 0; 592 } 593 594 private static class UnmodifiableListMultimap<K, V> 595 extends UnmodifiableMultimap<K, V> implements ListMultimap<K, V> { 596 UnmodifiableListMultimap(ListMultimap<K, V> delegate) { 597 super(delegate); 598 } 599 @Override public ListMultimap<K, V> delegate() { 600 return (ListMultimap<K, V>) super.delegate(); 601 } 602 @Override public List<V> get(K key) { 603 return Collections.unmodifiableList(delegate().get(key)); 604 } 605 @Override public List<V> removeAll(Object key) { 606 throw new UnsupportedOperationException(); 607 } 608 @Override public List<V> replaceValues( 609 K key, Iterable<? extends V> values) { 610 throw new UnsupportedOperationException(); 611 } 612 private static final long serialVersionUID = 0; 613 } 614 615 private static class UnmodifiableSetMultimap<K, V> 616 extends UnmodifiableMultimap<K, V> implements SetMultimap<K, V> { 617 UnmodifiableSetMultimap(SetMultimap<K, V> delegate) { 618 super(delegate); 619 } 620 @Override public SetMultimap<K, V> delegate() { 621 return (SetMultimap<K, V>) super.delegate(); 622 } 623 @Override public Set<V> get(K key) { 624 /* 625 * Note that this doesn't return a SortedSet when delegate is a 626 * SortedSetMultiset, unlike (SortedSet<V>) super.get(). 627 */ 628 return Collections.unmodifiableSet(delegate().get(key)); 629 } 630 @Override public Set<Map.Entry<K, V>> entries() { 631 return Maps.unmodifiableEntrySet(delegate().entries()); 632 } 633 @Override public Set<V> removeAll(Object key) { 634 throw new UnsupportedOperationException(); 635 } 636 @Override public Set<V> replaceValues( 637 K key, Iterable<? extends V> values) { 638 throw new UnsupportedOperationException(); 639 } 640 private static final long serialVersionUID = 0; 641 } 642 643 private static class UnmodifiableSortedSetMultimap<K, V> 644 extends UnmodifiableSetMultimap<K, V> implements SortedSetMultimap<K, V> { 645 UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) { 646 super(delegate); 647 } 648 @Override public SortedSetMultimap<K, V> delegate() { 649 return (SortedSetMultimap<K, V>) super.delegate(); 650 } 651 @Override public SortedSet<V> get(K key) { 652 return Collections.unmodifiableSortedSet(delegate().get(key)); 653 } 654 @Override public SortedSet<V> removeAll(Object key) { 655 throw new UnsupportedOperationException(); 656 } 657 @Override public SortedSet<V> replaceValues( 658 K key, Iterable<? extends V> values) { 659 throw new UnsupportedOperationException(); 660 } 661 @Override 662 public Comparator<? super V> valueComparator() { 663 return delegate().valueComparator(); 664 } 665 private static final long serialVersionUID = 0; 666 } 667 668 /** 669 * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the 670 * specified multimap. 671 * 672 * <p>You must follow the warnings described in {@link #synchronizedMultimap}. 673 * 674 * <p>The returned multimap will be serializable if the specified multimap is 675 * serializable. 676 * 677 * @param multimap the multimap to be wrapped 678 * @return a synchronized view of the specified multimap 679 */ 680 public static <K, V> SetMultimap<K, V> synchronizedSetMultimap( 681 SetMultimap<K, V> multimap) { 682 return Synchronized.setMultimap(multimap, null); 683 } 684 685 /** 686 * Returns an unmodifiable view of the specified {@code SetMultimap}. Query 687 * operations on the returned multimap "read through" to the specified 688 * multimap, and attempts to modify the returned multimap, either directly or 689 * through the multimap's views, result in an 690 * {@code UnsupportedOperationException}. 691 * 692 * <p>Note that the generated multimap's {@link Multimap#removeAll} and 693 * {@link Multimap#replaceValues} methods return collections that are 694 * modifiable. 695 * 696 * <p>The returned multimap will be serializable if the specified multimap is 697 * serializable. 698 * 699 * @param delegate the multimap for which an unmodifiable view is to be 700 * returned 701 * @return an unmodifiable view of the specified multimap 702 */ 703 public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap( 704 SetMultimap<K, V> delegate) { 705 if (delegate instanceof UnmodifiableSetMultimap || 706 delegate instanceof ImmutableSetMultimap) { 707 return delegate; 708 } 709 return new UnmodifiableSetMultimap<K, V>(delegate); 710 } 711 712 /** 713 * Simply returns its argument. 714 * 715 * @deprecated no need to use this 716 * @since 10.0 717 */ 718 @Deprecated public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap( 719 ImmutableSetMultimap<K, V> delegate) { 720 return checkNotNull(delegate); 721 } 722 723 /** 724 * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by 725 * the specified multimap. 726 * 727 * <p>You must follow the warnings described in {@link #synchronizedMultimap}. 728 * 729 * <p>The returned multimap will be serializable if the specified multimap is 730 * serializable. 731 * 732 * @param multimap the multimap to be wrapped 733 * @return a synchronized view of the specified multimap 734 */ 735 public static <K, V> SortedSetMultimap<K, V> 736 synchronizedSortedSetMultimap(SortedSetMultimap<K, V> multimap) { 737 return Synchronized.sortedSetMultimap(multimap, null); 738 } 739 740 /** 741 * Returns an unmodifiable view of the specified {@code SortedSetMultimap}. 742 * Query operations on the returned multimap "read through" to the specified 743 * multimap, and attempts to modify the returned multimap, either directly or 744 * through the multimap's views, result in an 745 * {@code UnsupportedOperationException}. 746 * 747 * <p>Note that the generated multimap's {@link Multimap#removeAll} and 748 * {@link Multimap#replaceValues} methods return collections that are 749 * modifiable. 750 * 751 * <p>The returned multimap will be serializable if the specified multimap is 752 * serializable. 753 * 754 * @param delegate the multimap for which an unmodifiable view is to be 755 * returned 756 * @return an unmodifiable view of the specified multimap 757 */ 758 public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap( 759 SortedSetMultimap<K, V> delegate) { 760 if (delegate instanceof UnmodifiableSortedSetMultimap) { 761 return delegate; 762 } 763 return new UnmodifiableSortedSetMultimap<K, V>(delegate); 764 } 765 766 /** 767 * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the 768 * specified multimap. 769 * 770 * <p>You must follow the warnings described in {@link #synchronizedMultimap}. 771 * 772 * @param multimap the multimap to be wrapped 773 * @return a synchronized view of the specified multimap 774 */ 775 public static <K, V> ListMultimap<K, V> synchronizedListMultimap( 776 ListMultimap<K, V> multimap) { 777 return Synchronized.listMultimap(multimap, null); 778 } 779 780 /** 781 * Returns an unmodifiable view of the specified {@code ListMultimap}. Query 782 * operations on the returned multimap "read through" to the specified 783 * multimap, and attempts to modify the returned multimap, either directly or 784 * through the multimap's views, result in an 785 * {@code UnsupportedOperationException}. 786 * 787 * <p>Note that the generated multimap's {@link Multimap#removeAll} and 788 * {@link Multimap#replaceValues} methods return collections that are 789 * modifiable. 790 * 791 * <p>The returned multimap will be serializable if the specified multimap is 792 * serializable. 793 * 794 * @param delegate the multimap for which an unmodifiable view is to be 795 * returned 796 * @return an unmodifiable view of the specified multimap 797 */ 798 public static <K, V> ListMultimap<K, V> unmodifiableListMultimap( 799 ListMultimap<K, V> delegate) { 800 if (delegate instanceof UnmodifiableListMultimap || 801 delegate instanceof ImmutableListMultimap) { 802 return delegate; 803 } 804 return new UnmodifiableListMultimap<K, V>(delegate); 805 } 806 807 /** 808 * Simply returns its argument. 809 * 810 * @deprecated no need to use this 811 * @since 10.0 812 */ 813 @Deprecated public static <K, V> ListMultimap<K, V> unmodifiableListMultimap( 814 ImmutableListMultimap<K, V> delegate) { 815 return checkNotNull(delegate); 816 } 817 818 /** 819 * Returns an unmodifiable view of the specified collection, preserving the 820 * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and 821 * {@code Collection}, in that order of preference. 822 * 823 * @param collection the collection for which to return an unmodifiable view 824 * @return an unmodifiable view of the collection 825 */ 826 private static <V> Collection<V> unmodifiableValueCollection( 827 Collection<V> collection) { 828 if (collection instanceof SortedSet) { 829 return Collections.unmodifiableSortedSet((SortedSet<V>) collection); 830 } else if (collection instanceof Set) { 831 return Collections.unmodifiableSet((Set<V>) collection); 832 } else if (collection instanceof List) { 833 return Collections.unmodifiableList((List<V>) collection); 834 } 835 return Collections.unmodifiableCollection(collection); 836 } 837 838 /** 839 * Returns an unmodifiable view of the specified collection of entries. The 840 * {@link Entry#setValue} operation throws an {@link 841 * UnsupportedOperationException}. If the specified collection is a {@code 842 * Set}, the returned collection is also a {@code Set}. 843 * 844 * @param entries the entries for which to return an unmodifiable view 845 * @return an unmodifiable view of the entries 846 */ 847 private static <K, V> Collection<Entry<K, V>> unmodifiableEntries( 848 Collection<Entry<K, V>> entries) { 849 if (entries instanceof Set) { 850 return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries); 851 } 852 return new Maps.UnmodifiableEntries<K, V>( 853 Collections.unmodifiableCollection(entries)); 854 } 855 856 /** 857 * Returns {@link ListMultimap#asMap multimap.asMap()}, with its type 858 * corrected from {@code Map<K, Collection<V>>} to {@code Map<K, List<V>>}. 859 * 860 * @since 15.0 861 */ 862 @Beta 863 @SuppressWarnings("unchecked") 864 // safe by specification of ListMultimap.asMap() 865 public static <K, V> Map<K, List<V>> asMap(ListMultimap<K, V> multimap) { 866 return (Map<K, List<V>>) (Map<K, ?>) multimap.asMap(); 867 } 868 869 /** 870 * Returns {@link SetMultimap#asMap multimap.asMap()}, with its type corrected 871 * from {@code Map<K, Collection<V>>} to {@code Map<K, Set<V>>}. 872 * 873 * @since 15.0 874 */ 875 @Beta 876 @SuppressWarnings("unchecked") 877 // safe by specification of SetMultimap.asMap() 878 public static <K, V> Map<K, Set<V>> asMap(SetMultimap<K, V> multimap) { 879 return (Map<K, Set<V>>) (Map<K, ?>) multimap.asMap(); 880 } 881 882 /** 883 * Returns {@link SortedSetMultimap#asMap multimap.asMap()}, with its type 884 * corrected from {@code Map<K, Collection<V>>} to 885 * {@code Map<K, SortedSet<V>>}. 886 * 887 * @since 15.0 888 */ 889 @Beta 890 @SuppressWarnings("unchecked") 891 // safe by specification of SortedSetMultimap.asMap() 892 public static <K, V> Map<K, SortedSet<V>> asMap( 893 SortedSetMultimap<K, V> multimap) { 894 return (Map<K, SortedSet<V>>) (Map<K, ?>) multimap.asMap(); 895 } 896 897 /** 898 * Returns {@link Multimap#asMap multimap.asMap()}. This is provided for 899 * parity with the other more strongly-typed {@code asMap()} implementations. 900 * 901 * @since 15.0 902 */ 903 @Beta 904 public static <K, V> Map<K, Collection<V>> asMap(Multimap<K, V> multimap) { 905 return multimap.asMap(); 906 } 907 908 /** 909 * Returns a multimap view of the specified map. The multimap is backed by the 910 * map, so changes to the map are reflected in the multimap, and vice versa. 911 * If the map is modified while an iteration over one of the multimap's 912 * collection views is in progress (except through the iterator's own {@code 913 * remove} operation, or through the {@code setValue} operation on a map entry 914 * returned by the iterator), the results of the iteration are undefined. 915 * 916 * <p>The multimap supports mapping removal, which removes the corresponding 917 * mapping from the map. It does not support any operations which might add 918 * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}. 919 * 920 * <p>The returned multimap will be serializable if the specified map is 921 * serializable. 922 * 923 * @param map the backing map for the returned multimap view 924 */ 925 public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) { 926 return new MapMultimap<K, V>(map); 927 } 928 929 /** @see Multimaps#forMap */ 930 private static class MapMultimap<K, V> 931 extends AbstractMultimap<K, V> implements SetMultimap<K, V>, Serializable { 932 final Map<K, V> map; 933 934 MapMultimap(Map<K, V> map) { 935 this.map = checkNotNull(map); 936 } 937 938 @Override 939 public int size() { 940 return map.size(); 941 } 942 943 @Override 944 public boolean containsKey(Object key) { 945 return map.containsKey(key); 946 } 947 948 @Override 949 public boolean containsValue(Object value) { 950 return map.containsValue(value); 951 } 952 953 @Override 954 public boolean containsEntry(Object key, Object value) { 955 return map.entrySet().contains(Maps.immutableEntry(key, value)); 956 } 957 958 @Override 959 public Set<V> get(final K key) { 960 return new Sets.ImprovedAbstractSet<V>() { 961 @Override public Iterator<V> iterator() { 962 return new Iterator<V>() { 963 int i; 964 965 @Override 966 public boolean hasNext() { 967 return (i == 0) && map.containsKey(key); 968 } 969 970 @Override 971 public V next() { 972 if (!hasNext()) { 973 throw new NoSuchElementException(); 974 } 975 i++; 976 return map.get(key); 977 } 978 979 @Override 980 public void remove() { 981 checkRemove(i == 1); 982 i = -1; 983 map.remove(key); 984 } 985 }; 986 } 987 988 @Override public int size() { 989 return map.containsKey(key) ? 1 : 0; 990 } 991 }; 992 } 993 994 @Override 995 public boolean put(K key, V value) { 996 throw new UnsupportedOperationException(); 997 } 998 999 @Override 1000 public boolean putAll(K key, Iterable<? extends V> values) { 1001 throw new UnsupportedOperationException(); 1002 } 1003 1004 @Override 1005 public boolean putAll(Multimap<? extends K, ? extends V> multimap) { 1006 throw new UnsupportedOperationException(); 1007 } 1008 1009 @Override 1010 public Set<V> replaceValues(K key, Iterable<? extends V> values) { 1011 throw new UnsupportedOperationException(); 1012 } 1013 1014 @Override 1015 public boolean remove(Object key, Object value) { 1016 return map.entrySet().remove(Maps.immutableEntry(key, value)); 1017 } 1018 1019 @Override 1020 public Set<V> removeAll(Object key) { 1021 Set<V> values = new HashSet<V>(2); 1022 if (!map.containsKey(key)) { 1023 return values; 1024 } 1025 values.add(map.remove(key)); 1026 return values; 1027 } 1028 1029 @Override 1030 public void clear() { 1031 map.clear(); 1032 } 1033 1034 @Override 1035 public Set<K> keySet() { 1036 return map.keySet(); 1037 } 1038 1039 @Override 1040 public Collection<V> values() { 1041 return map.values(); 1042 } 1043 1044 @Override 1045 public Set<Entry<K, V>> entries() { 1046 return map.entrySet(); 1047 } 1048 1049 @Override 1050 Iterator<Entry<K, V>> entryIterator() { 1051 return map.entrySet().iterator(); 1052 } 1053 1054 @Override 1055 Map<K, Collection<V>> createAsMap() { 1056 return new AsMap<K, V>(this); 1057 } 1058 1059 @Override public int hashCode() { 1060 return map.hashCode(); 1061 } 1062 1063 private static final long serialVersionUID = 7845222491160860175L; 1064 } 1065 1066 /** 1067 * Returns a view of a multimap where each value is transformed by a function. 1068 * All other properties of the multimap, such as iteration order, are left 1069 * intact. For example, the code: <pre> {@code 1070 * 1071 * Multimap<String, Integer> multimap = 1072 * ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6); 1073 * Function<Integer, String> square = new Function<Integer, String>() { 1074 * public String apply(Integer in) { 1075 * return Integer.toString(in * in); 1076 * } 1077 * }; 1078 * Multimap<String, String> transformed = 1079 * Multimaps.transformValues(multimap, square); 1080 * System.out.println(transformed);}</pre> 1081 * 1082 * ... prints {@code {a=[4, 16], b=[9, 9], c=[36]}}. 1083 * 1084 * <p>Changes in the underlying multimap are reflected in this view. 1085 * Conversely, this view supports removal operations, and these are reflected 1086 * in the underlying multimap. 1087 * 1088 * <p>It's acceptable for the underlying multimap to contain null keys, and 1089 * even null values provided that the function is capable of accepting null 1090 * input. The transformed multimap might contain null values, if the function 1091 * sometimes gives a null result. 1092 * 1093 * <p>The returned multimap is not thread-safe or serializable, even if the 1094 * underlying multimap is. The {@code equals} and {@code hashCode} methods 1095 * of the returned multimap are meaningless, since there is not a definition 1096 * of {@code equals} or {@code hashCode} for general collections, and 1097 * {@code get()} will return a general {@code Collection} as opposed to a 1098 * {@code List} or a {@code Set}. 1099 * 1100 * <p>The function is applied lazily, invoked when needed. This is necessary 1101 * for the returned multimap to be a view, but it means that the function will 1102 * be applied many times for bulk operations like 1103 * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to 1104 * perform well, {@code function} should be fast. To avoid lazy evaluation 1105 * when the returned multimap doesn't need to be a view, copy the returned 1106 * multimap into a new multimap of your choosing. 1107 * 1108 * @since 7.0 1109 */ 1110 public static <K, V1, V2> Multimap<K, V2> transformValues( 1111 Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) { 1112 checkNotNull(function); 1113 EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function); 1114 return transformEntries(fromMultimap, transformer); 1115 } 1116 1117 /** 1118 * Returns a view of a multimap whose values are derived from the original 1119 * multimap's entries. In contrast to {@link #transformValues}, this method's 1120 * entry-transformation logic may depend on the key as well as the value. 1121 * 1122 * <p>All other properties of the transformed multimap, such as iteration 1123 * order, are left intact. For example, the code: <pre> {@code 1124 * 1125 * SetMultimap<String, Integer> multimap = 1126 * ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6); 1127 * EntryTransformer<String, Integer, String> transformer = 1128 * new EntryTransformer<String, Integer, String>() { 1129 * public String transformEntry(String key, Integer value) { 1130 * return (value >= 0) ? key : "no" + key; 1131 * } 1132 * }; 1133 * Multimap<String, String> transformed = 1134 * Multimaps.transformEntries(multimap, transformer); 1135 * System.out.println(transformed);}</pre> 1136 * 1137 * ... prints {@code {a=[a, a], b=[nob]}}. 1138 * 1139 * <p>Changes in the underlying multimap are reflected in this view. 1140 * Conversely, this view supports removal operations, and these are reflected 1141 * in the underlying multimap. 1142 * 1143 * <p>It's acceptable for the underlying multimap to contain null keys and 1144 * null values provided that the transformer is capable of accepting null 1145 * inputs. The transformed multimap might contain null values if the 1146 * transformer sometimes gives a null result. 1147 * 1148 * <p>The returned multimap is not thread-safe or serializable, even if the 1149 * underlying multimap is. The {@code equals} and {@code hashCode} methods 1150 * of the returned multimap are meaningless, since there is not a definition 1151 * of {@code equals} or {@code hashCode} for general collections, and 1152 * {@code get()} will return a general {@code Collection} as opposed to a 1153 * {@code List} or a {@code Set}. 1154 * 1155 * <p>The transformer is applied lazily, invoked when needed. This is 1156 * necessary for the returned multimap to be a view, but it means that the 1157 * transformer will be applied many times for bulk operations like {@link 1158 * Multimap#containsValue} and {@link Object#toString}. For this to perform 1159 * well, {@code transformer} should be fast. To avoid lazy evaluation when the 1160 * returned multimap doesn't need to be a view, copy the returned multimap 1161 * into a new multimap of your choosing. 1162 * 1163 * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 1164 * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 1165 * that {@code k2} is also of type {@code K}. Using an {@code 1166 * EntryTransformer} key type for which this may not hold, such as {@code 1167 * ArrayList}, may risk a {@code ClassCastException} when calling methods on 1168 * the transformed multimap. 1169 * 1170 * @since 7.0 1171 */ 1172 public static <K, V1, V2> Multimap<K, V2> transformEntries( 1173 Multimap<K, V1> fromMap, 1174 EntryTransformer<? super K, ? super V1, V2> transformer) { 1175 return new TransformedEntriesMultimap<K, V1, V2>(fromMap, transformer); 1176 } 1177 1178 private static class TransformedEntriesMultimap<K, V1, V2> 1179 extends AbstractMultimap<K, V2> { 1180 final Multimap<K, V1> fromMultimap; 1181 final EntryTransformer<? super K, ? super V1, V2> transformer; 1182 1183 TransformedEntriesMultimap(Multimap<K, V1> fromMultimap, 1184 final EntryTransformer<? super K, ? super V1, V2> transformer) { 1185 this.fromMultimap = checkNotNull(fromMultimap); 1186 this.transformer = checkNotNull(transformer); 1187 } 1188 1189 Collection<V2> transform(K key, Collection<V1> values) { 1190 Function<? super V1, V2> function = 1191 Maps.asValueToValueFunction(transformer, key); 1192 if (values instanceof List) { 1193 return Lists.transform((List<V1>) values, function); 1194 } else { 1195 return Collections2.transform(values, function); 1196 } 1197 } 1198 1199 @Override 1200 Map<K, Collection<V2>> createAsMap() { 1201 return Maps.transformEntries(fromMultimap.asMap(), 1202 new EntryTransformer<K, Collection<V1>, Collection<V2>>() { 1203 @Override public Collection<V2> transformEntry( 1204 K key, Collection<V1> value) { 1205 return transform(key, value); 1206 } 1207 }); 1208 } 1209 1210 @Override public void clear() { 1211 fromMultimap.clear(); 1212 } 1213 1214 @Override public boolean containsKey(Object key) { 1215 return fromMultimap.containsKey(key); 1216 } 1217 1218 @Override 1219 Iterator<Entry<K, V2>> entryIterator() { 1220 return Iterators.transform(fromMultimap.entries().iterator(), 1221 Maps.<K, V1, V2>asEntryToEntryFunction(transformer)); 1222 } 1223 1224 @Override public Collection<V2> get(final K key) { 1225 return transform(key, fromMultimap.get(key)); 1226 } 1227 1228 @Override public boolean isEmpty() { 1229 return fromMultimap.isEmpty(); 1230 } 1231 1232 @Override public Set<K> keySet() { 1233 return fromMultimap.keySet(); 1234 } 1235 1236 @Override public Multiset<K> keys() { 1237 return fromMultimap.keys(); 1238 } 1239 1240 @Override public boolean put(K key, V2 value) { 1241 throw new UnsupportedOperationException(); 1242 } 1243 1244 @Override public boolean putAll(K key, Iterable<? extends V2> values) { 1245 throw new UnsupportedOperationException(); 1246 } 1247 1248 @Override public boolean putAll( 1249 Multimap<? extends K, ? extends V2> multimap) { 1250 throw new UnsupportedOperationException(); 1251 } 1252 1253 @SuppressWarnings("unchecked") 1254 @Override public boolean remove(Object key, Object value) { 1255 return get((K) key).remove(value); 1256 } 1257 1258 @SuppressWarnings("unchecked") 1259 @Override public Collection<V2> removeAll(Object key) { 1260 return transform((K) key, fromMultimap.removeAll(key)); 1261 } 1262 1263 @Override public Collection<V2> replaceValues( 1264 K key, Iterable<? extends V2> values) { 1265 throw new UnsupportedOperationException(); 1266 } 1267 1268 @Override public int size() { 1269 return fromMultimap.size(); 1270 } 1271 1272 @Override 1273 Collection<V2> createValues() { 1274 return Collections2.transform( 1275 fromMultimap.entries(), Maps.<K, V1, V2>asEntryToValueFunction(transformer)); 1276 } 1277 } 1278 1279 /** 1280 * Returns a view of a {@code ListMultimap} where each value is transformed by 1281 * a function. All other properties of the multimap, such as iteration order, 1282 * are left intact. For example, the code: <pre> {@code 1283 * 1284 * ListMultimap<String, Integer> multimap 1285 * = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9); 1286 * Function<Integer, Double> sqrt = 1287 * new Function<Integer, Double>() { 1288 * public Double apply(Integer in) { 1289 * return Math.sqrt((int) in); 1290 * } 1291 * }; 1292 * ListMultimap<String, Double> transformed = Multimaps.transformValues(map, 1293 * sqrt); 1294 * System.out.println(transformed);}</pre> 1295 * 1296 * ... prints {@code {a=[2.0, 4.0], b=[3.0]}}. 1297 * 1298 * <p>Changes in the underlying multimap are reflected in this view. 1299 * Conversely, this view supports removal operations, and these are reflected 1300 * in the underlying multimap. 1301 * 1302 * <p>It's acceptable for the underlying multimap to contain null keys, and 1303 * even null values provided that the function is capable of accepting null 1304 * input. The transformed multimap might contain null values, if the function 1305 * sometimes gives a null result. 1306 * 1307 * <p>The returned multimap is not thread-safe or serializable, even if the 1308 * underlying multimap is. 1309 * 1310 * <p>The function is applied lazily, invoked when needed. This is necessary 1311 * for the returned multimap to be a view, but it means that the function will 1312 * be applied many times for bulk operations like 1313 * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to 1314 * perform well, {@code function} should be fast. To avoid lazy evaluation 1315 * when the returned multimap doesn't need to be a view, copy the returned 1316 * multimap into a new multimap of your choosing. 1317 * 1318 * @since 7.0 1319 */ 1320 public static <K, V1, V2> ListMultimap<K, V2> transformValues( 1321 ListMultimap<K, V1> fromMultimap, 1322 final Function<? super V1, V2> function) { 1323 checkNotNull(function); 1324 EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function); 1325 return transformEntries(fromMultimap, transformer); 1326 } 1327 1328 /** 1329 * Returns a view of a {@code ListMultimap} whose values are derived from the 1330 * original multimap's entries. In contrast to 1331 * {@link #transformValues(ListMultimap, Function)}, this method's 1332 * entry-transformation logic may depend on the key as well as the value. 1333 * 1334 * <p>All other properties of the transformed multimap, such as iteration 1335 * order, are left intact. For example, the code: <pre> {@code 1336 * 1337 * Multimap<String, Integer> multimap = 1338 * ImmutableMultimap.of("a", 1, "a", 4, "b", 6); 1339 * EntryTransformer<String, Integer, String> transformer = 1340 * new EntryTransformer<String, Integer, String>() { 1341 * public String transformEntry(String key, Integer value) { 1342 * return key + value; 1343 * } 1344 * }; 1345 * Multimap<String, String> transformed = 1346 * Multimaps.transformEntries(multimap, transformer); 1347 * System.out.println(transformed);}</pre> 1348 * 1349 * ... prints {@code {"a"=["a1", "a4"], "b"=["b6"]}}. 1350 * 1351 * <p>Changes in the underlying multimap are reflected in this view. 1352 * Conversely, this view supports removal operations, and these are reflected 1353 * in the underlying multimap. 1354 * 1355 * <p>It's acceptable for the underlying multimap to contain null keys and 1356 * null values provided that the transformer is capable of accepting null 1357 * inputs. The transformed multimap might contain null values if the 1358 * transformer sometimes gives a null result. 1359 * 1360 * <p>The returned multimap is not thread-safe or serializable, even if the 1361 * underlying multimap is. 1362 * 1363 * <p>The transformer is applied lazily, invoked when needed. This is 1364 * necessary for the returned multimap to be a view, but it means that the 1365 * transformer will be applied many times for bulk operations like {@link 1366 * Multimap#containsValue} and {@link Object#toString}. For this to perform 1367 * well, {@code transformer} should be fast. To avoid lazy evaluation when the 1368 * returned multimap doesn't need to be a view, copy the returned multimap 1369 * into a new multimap of your choosing. 1370 * 1371 * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 1372 * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 1373 * that {@code k2} is also of type {@code K}. Using an {@code 1374 * EntryTransformer} key type for which this may not hold, such as {@code 1375 * ArrayList}, may risk a {@code ClassCastException} when calling methods on 1376 * the transformed multimap. 1377 * 1378 * @since 7.0 1379 */ 1380 public static <K, V1, V2> ListMultimap<K, V2> transformEntries( 1381 ListMultimap<K, V1> fromMap, 1382 EntryTransformer<? super K, ? super V1, V2> transformer) { 1383 return new TransformedEntriesListMultimap<K, V1, V2>(fromMap, transformer); 1384 } 1385 1386 private static final class TransformedEntriesListMultimap<K, V1, V2> 1387 extends TransformedEntriesMultimap<K, V1, V2> 1388 implements ListMultimap<K, V2> { 1389 1390 TransformedEntriesListMultimap(ListMultimap<K, V1> fromMultimap, 1391 EntryTransformer<? super K, ? super V1, V2> transformer) { 1392 super(fromMultimap, transformer); 1393 } 1394 1395 @Override List<V2> transform(K key, Collection<V1> values) { 1396 return Lists.transform((List<V1>) values, Maps.asValueToValueFunction(transformer, key)); 1397 } 1398 1399 @Override public List<V2> get(K key) { 1400 return transform(key, fromMultimap.get(key)); 1401 } 1402 1403 @SuppressWarnings("unchecked") 1404 @Override public List<V2> removeAll(Object key) { 1405 return transform((K) key, fromMultimap.removeAll(key)); 1406 } 1407 1408 @Override public List<V2> replaceValues( 1409 K key, Iterable<? extends V2> values) { 1410 throw new UnsupportedOperationException(); 1411 } 1412 } 1413 1414 /** 1415 * Creates an index {@code ImmutableListMultimap} that contains the results of 1416 * applying a specified function to each item in an {@code Iterable} of 1417 * values. Each value will be stored as a value in the resulting multimap, 1418 * yielding a multimap with the same size as the input iterable. The key used 1419 * to store that value in the multimap will be the result of calling the 1420 * function on that value. The resulting multimap is created as an immutable 1421 * snapshot. In the returned multimap, keys appear in the order they are first 1422 * encountered, and the values corresponding to each key appear in the same 1423 * order as they are encountered. 1424 * 1425 * <p>For example, <pre> {@code 1426 * 1427 * List<String> badGuys = 1428 * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde"); 1429 * Function<String, Integer> stringLengthFunction = ...; 1430 * Multimap<Integer, String> index = 1431 * Multimaps.index(badGuys, stringLengthFunction); 1432 * System.out.println(index);}</pre> 1433 * 1434 * <p>prints <pre> {@code 1435 * 1436 * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre> 1437 * 1438 * <p>The returned multimap is serializable if its keys and values are all 1439 * serializable. 1440 * 1441 * @param values the values to use when constructing the {@code 1442 * ImmutableListMultimap} 1443 * @param keyFunction the function used to produce the key for each value 1444 * @return {@code ImmutableListMultimap} mapping the result of evaluating the 1445 * function {@code keyFunction} on each value in the input collection to 1446 * that value 1447 * @throws NullPointerException if any of the following cases is true: 1448 * <ul> 1449 * <li>{@code values} is null 1450 * <li>{@code keyFunction} is null 1451 * <li>An element in {@code values} is null 1452 * <li>{@code keyFunction} returns {@code null} for any element of {@code 1453 * values} 1454 * </ul> 1455 */ 1456 public static <K, V> ImmutableListMultimap<K, V> index( 1457 Iterable<V> values, Function<? super V, K> keyFunction) { 1458 return index(values.iterator(), keyFunction); 1459 } 1460 1461 /** 1462 * Creates an index {@code ImmutableListMultimap} that contains the results of 1463 * applying a specified function to each item in an {@code Iterator} of 1464 * values. Each value will be stored as a value in the resulting multimap, 1465 * yielding a multimap with the same size as the input iterator. The key used 1466 * to store that value in the multimap will be the result of calling the 1467 * function on that value. The resulting multimap is created as an immutable 1468 * snapshot. In the returned multimap, keys appear in the order they are first 1469 * encountered, and the values corresponding to each key appear in the same 1470 * order as they are encountered. 1471 * 1472 * <p>For example, <pre> {@code 1473 * 1474 * List<String> badGuys = 1475 * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde"); 1476 * Function<String, Integer> stringLengthFunction = ...; 1477 * Multimap<Integer, String> index = 1478 * Multimaps.index(badGuys.iterator(), stringLengthFunction); 1479 * System.out.println(index);}</pre> 1480 * 1481 * <p>prints <pre> {@code 1482 * 1483 * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre> 1484 * 1485 * <p>The returned multimap is serializable if its keys and values are all 1486 * serializable. 1487 * 1488 * @param values the values to use when constructing the {@code 1489 * ImmutableListMultimap} 1490 * @param keyFunction the function used to produce the key for each value 1491 * @return {@code ImmutableListMultimap} mapping the result of evaluating the 1492 * function {@code keyFunction} on each value in the input collection to 1493 * that value 1494 * @throws NullPointerException if any of the following cases is true: 1495 * <ul> 1496 * <li>{@code values} is null 1497 * <li>{@code keyFunction} is null 1498 * <li>An element in {@code values} is null 1499 * <li>{@code keyFunction} returns {@code null} for any element of {@code 1500 * values} 1501 * </ul> 1502 * @since 10.0 1503 */ 1504 public static <K, V> ImmutableListMultimap<K, V> index( 1505 Iterator<V> values, Function<? super V, K> keyFunction) { 1506 checkNotNull(keyFunction); 1507 ImmutableListMultimap.Builder<K, V> builder 1508 = ImmutableListMultimap.builder(); 1509 while (values.hasNext()) { 1510 V value = values.next(); 1511 checkNotNull(value, values); 1512 builder.put(keyFunction.apply(value), value); 1513 } 1514 return builder.build(); 1515 } 1516 1517 static class Keys<K, V> extends AbstractMultiset<K> { 1518 @Weak final Multimap<K, V> multimap; 1519 1520 Keys(Multimap<K, V> multimap) { 1521 this.multimap = multimap; 1522 } 1523 1524 @Override Iterator<Multiset.Entry<K>> entryIterator() { 1525 return new TransformedIterator<Map.Entry<K, Collection<V>>, Multiset.Entry<K>>( 1526 multimap.asMap().entrySet().iterator()) { 1527 @Override 1528 Multiset.Entry<K> transform( 1529 final Map.Entry<K, Collection<V>> backingEntry) { 1530 return new Multisets.AbstractEntry<K>() { 1531 @Override 1532 public K getElement() { 1533 return backingEntry.getKey(); 1534 } 1535 1536 @Override 1537 public int getCount() { 1538 return backingEntry.getValue().size(); 1539 } 1540 }; 1541 } 1542 }; 1543 } 1544 1545 @Override int distinctElements() { 1546 return multimap.asMap().size(); 1547 } 1548 1549 @Override Set<Multiset.Entry<K>> createEntrySet() { 1550 return new KeysEntrySet(); 1551 } 1552 1553 @WeakOuter 1554 class KeysEntrySet extends Multisets.EntrySet<K> { 1555 @Override Multiset<K> multiset() { 1556 return Keys.this; 1557 } 1558 1559 @Override public Iterator<Multiset.Entry<K>> iterator() { 1560 return entryIterator(); 1561 } 1562 1563 @Override public int size() { 1564 return distinctElements(); 1565 } 1566 1567 @Override public boolean isEmpty() { 1568 return multimap.isEmpty(); 1569 } 1570 1571 @Override public boolean contains(@Nullable Object o) { 1572 if (o instanceof Multiset.Entry) { 1573 Multiset.Entry<?> entry = (Multiset.Entry<?>) o; 1574 Collection<V> collection = multimap.asMap().get(entry.getElement()); 1575 return collection != null && collection.size() == entry.getCount(); 1576 } 1577 return false; 1578 } 1579 1580 @Override public boolean remove(@Nullable Object o) { 1581 if (o instanceof Multiset.Entry) { 1582 Multiset.Entry<?> entry = (Multiset.Entry<?>) o; 1583 Collection<V> collection = multimap.asMap().get(entry.getElement()); 1584 if (collection != null && collection.size() == entry.getCount()) { 1585 collection.clear(); 1586 return true; 1587 } 1588 } 1589 return false; 1590 } 1591 } 1592 1593 @Override public boolean contains(@Nullable Object element) { 1594 return multimap.containsKey(element); 1595 } 1596 1597 @Override public Iterator<K> iterator() { 1598 return Maps.keyIterator(multimap.entries().iterator()); 1599 } 1600 1601 @Override public int count(@Nullable Object element) { 1602 Collection<V> values = Maps.safeGet(multimap.asMap(), element); 1603 return (values == null) ? 0 : values.size(); 1604 } 1605 1606 @Override public int remove(@Nullable Object element, int occurrences) { 1607 checkNonnegative(occurrences, "occurrences"); 1608 if (occurrences == 0) { 1609 return count(element); 1610 } 1611 1612 Collection<V> values = Maps.safeGet(multimap.asMap(), element); 1613 1614 if (values == null) { 1615 return 0; 1616 } 1617 1618 int oldCount = values.size(); 1619 if (occurrences >= oldCount) { 1620 values.clear(); 1621 } else { 1622 Iterator<V> iterator = values.iterator(); 1623 for (int i = 0; i < occurrences; i++) { 1624 iterator.next(); 1625 iterator.remove(); 1626 } 1627 } 1628 return oldCount; 1629 } 1630 1631 @Override public void clear() { 1632 multimap.clear(); 1633 } 1634 1635 @Override public Set<K> elementSet() { 1636 return multimap.keySet(); 1637 } 1638 } 1639 1640 /** 1641 * A skeleton implementation of {@link Multimap#entries()}. 1642 */ 1643 abstract static class Entries<K, V> extends 1644 AbstractCollection<Map.Entry<K, V>> { 1645 abstract Multimap<K, V> multimap(); 1646 1647 @Override public int size() { 1648 return multimap().size(); 1649 } 1650 1651 @Override public boolean contains(@Nullable Object o) { 1652 if (o instanceof Map.Entry) { 1653 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; 1654 return multimap().containsEntry(entry.getKey(), entry.getValue()); 1655 } 1656 return false; 1657 } 1658 1659 @Override public boolean remove(@Nullable Object o) { 1660 if (o instanceof Map.Entry) { 1661 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; 1662 return multimap().remove(entry.getKey(), entry.getValue()); 1663 } 1664 return false; 1665 } 1666 1667 @Override public void clear() { 1668 multimap().clear(); 1669 } 1670 } 1671 1672 /** 1673 * A skeleton implementation of {@link Multimap#asMap()}. 1674 */ 1675 static final class AsMap<K, V> extends 1676 Maps.ViewCachingAbstractMap<K, Collection<V>> { 1677 @Weak private final Multimap<K, V> multimap; 1678 1679 AsMap(Multimap<K, V> multimap) { 1680 this.multimap = checkNotNull(multimap); 1681 } 1682 1683 @Override public int size() { 1684 return multimap.keySet().size(); 1685 } 1686 1687 @Override protected Set<Entry<K, Collection<V>>> createEntrySet() { 1688 return new EntrySet(); 1689 } 1690 1691 void removeValuesForKey(Object key) { 1692 multimap.keySet().remove(key); 1693 } 1694 1695 @WeakOuter 1696 class EntrySet extends Maps.EntrySet<K, Collection<V>> { 1697 @Override Map<K, Collection<V>> map() { 1698 return AsMap.this; 1699 } 1700 1701 @Override public Iterator<Entry<K, Collection<V>>> iterator() { 1702 return Maps.asMapEntryIterator(multimap.keySet(), new Function<K, Collection<V>>() { 1703 @Override 1704 public Collection<V> apply(K key) { 1705 return multimap.get(key); 1706 } 1707 }); 1708 } 1709 1710 @Override public boolean remove(Object o) { 1711 if (!contains(o)) { 1712 return false; 1713 } 1714 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; 1715 removeValuesForKey(entry.getKey()); 1716 return true; 1717 } 1718 } 1719 1720 @SuppressWarnings("unchecked") 1721 @Override public Collection<V> get(Object key) { 1722 return containsKey(key) ? multimap.get((K) key) : null; 1723 } 1724 1725 @Override public Collection<V> remove(Object key) { 1726 return containsKey(key) ? multimap.removeAll(key) : null; 1727 } 1728 1729 @Override public Set<K> keySet() { 1730 return multimap.keySet(); 1731 } 1732 1733 @Override public boolean isEmpty() { 1734 return multimap.isEmpty(); 1735 } 1736 1737 @Override public boolean containsKey(Object key) { 1738 return multimap.containsKey(key); 1739 } 1740 1741 @Override public void clear() { 1742 multimap.clear(); 1743 } 1744 } 1745 1746 /** 1747 * Returns a multimap containing the mappings in {@code unfiltered} whose keys 1748 * satisfy a predicate. The returned multimap is a live view of 1749 * {@code unfiltered}; changes to one affect the other. 1750 * 1751 * <p>The resulting multimap's views have iterators that don't support 1752 * {@code remove()}, but all other methods are supported by the multimap and 1753 * its views. When adding a key that doesn't satisfy the predicate, the 1754 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 1755 * methods throw an {@link IllegalArgumentException}. 1756 * 1757 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 1758 * the filtered multimap or its views, only mappings whose keys satisfy the 1759 * filter will be removed from the underlying multimap. 1760 * 1761 * <p>The returned multimap isn't threadsafe or serializable, even if 1762 * {@code unfiltered} is. 1763 * 1764 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 1765 * across every key/value mapping in the underlying multimap and determine 1766 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1767 * faster to copy the filtered multimap and use the copy. 1768 * 1769 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, 1770 * as documented at {@link Predicate#apply}. Do not provide a predicate such 1771 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent 1772 * with equals. 1773 * 1774 * @since 11.0 1775 */ 1776 @CheckReturnValue 1777 public static <K, V> Multimap<K, V> filterKeys( 1778 Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 1779 if (unfiltered instanceof SetMultimap) { 1780 return filterKeys((SetMultimap<K, V>) unfiltered, keyPredicate); 1781 } else if (unfiltered instanceof ListMultimap) { 1782 return filterKeys((ListMultimap<K, V>) unfiltered, keyPredicate); 1783 } else if (unfiltered instanceof FilteredKeyMultimap) { 1784 FilteredKeyMultimap<K, V> prev = (FilteredKeyMultimap<K, V>) unfiltered; 1785 return new FilteredKeyMultimap<K, V>(prev.unfiltered, 1786 Predicates.and(prev.keyPredicate, keyPredicate)); 1787 } else if (unfiltered instanceof FilteredMultimap) { 1788 FilteredMultimap<K, V> prev = (FilteredMultimap<K, V>) unfiltered; 1789 return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate)); 1790 } else { 1791 return new FilteredKeyMultimap<K, V>(unfiltered, keyPredicate); 1792 } 1793 } 1794 1795 /** 1796 * Returns a multimap containing the mappings in {@code unfiltered} whose keys 1797 * satisfy a predicate. The returned multimap is a live view of 1798 * {@code unfiltered}; changes to one affect the other. 1799 * 1800 * <p>The resulting multimap's views have iterators that don't support 1801 * {@code remove()}, but all other methods are supported by the multimap and 1802 * its views. When adding a key that doesn't satisfy the predicate, the 1803 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 1804 * methods throw an {@link IllegalArgumentException}. 1805 * 1806 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 1807 * the filtered multimap or its views, only mappings whose keys satisfy the 1808 * filter will be removed from the underlying multimap. 1809 * 1810 * <p>The returned multimap isn't threadsafe or serializable, even if 1811 * {@code unfiltered} is. 1812 * 1813 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 1814 * across every key/value mapping in the underlying multimap and determine 1815 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1816 * faster to copy the filtered multimap and use the copy. 1817 * 1818 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, 1819 * as documented at {@link Predicate#apply}. Do not provide a predicate such 1820 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent 1821 * with equals. 1822 * 1823 * @since 14.0 1824 */ 1825 @CheckReturnValue 1826 public static <K, V> SetMultimap<K, V> filterKeys( 1827 SetMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 1828 if (unfiltered instanceof FilteredKeySetMultimap) { 1829 FilteredKeySetMultimap<K, V> prev = (FilteredKeySetMultimap<K, V>) unfiltered; 1830 return new FilteredKeySetMultimap<K, V>(prev.unfiltered(), 1831 Predicates.and(prev.keyPredicate, keyPredicate)); 1832 } else if (unfiltered instanceof FilteredSetMultimap) { 1833 FilteredSetMultimap<K, V> prev = (FilteredSetMultimap<K, V>) unfiltered; 1834 return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate)); 1835 } else { 1836 return new FilteredKeySetMultimap<K, V>(unfiltered, keyPredicate); 1837 } 1838 } 1839 1840 /** 1841 * Returns a multimap containing the mappings in {@code unfiltered} whose keys 1842 * satisfy a predicate. The returned multimap is a live view of 1843 * {@code unfiltered}; changes to one affect the other. 1844 * 1845 * <p>The resulting multimap's views have iterators that don't support 1846 * {@code remove()}, but all other methods are supported by the multimap and 1847 * its views. When adding a key that doesn't satisfy the predicate, the 1848 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 1849 * methods throw an {@link IllegalArgumentException}. 1850 * 1851 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 1852 * the filtered multimap or its views, only mappings whose keys satisfy the 1853 * filter will be removed from the underlying multimap. 1854 * 1855 * <p>The returned multimap isn't threadsafe or serializable, even if 1856 * {@code unfiltered} is. 1857 * 1858 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 1859 * across every key/value mapping in the underlying multimap and determine 1860 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1861 * faster to copy the filtered multimap and use the copy. 1862 * 1863 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, 1864 * as documented at {@link Predicate#apply}. Do not provide a predicate such 1865 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent 1866 * with equals. 1867 * 1868 * @since 14.0 1869 */ 1870 @CheckReturnValue 1871 public static <K, V> ListMultimap<K, V> filterKeys( 1872 ListMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 1873 if (unfiltered instanceof FilteredKeyListMultimap) { 1874 FilteredKeyListMultimap<K, V> prev = (FilteredKeyListMultimap<K, V>) unfiltered; 1875 return new FilteredKeyListMultimap<K, V>(prev.unfiltered(), 1876 Predicates.and(prev.keyPredicate, keyPredicate)); 1877 } else { 1878 return new FilteredKeyListMultimap<K, V>(unfiltered, keyPredicate); 1879 } 1880 } 1881 1882 /** 1883 * Returns a multimap containing the mappings in {@code unfiltered} whose values 1884 * satisfy a predicate. The returned multimap is a live view of 1885 * {@code unfiltered}; changes to one affect the other. 1886 * 1887 * <p>The resulting multimap's views have iterators that don't support 1888 * {@code remove()}, but all other methods are supported by the multimap and 1889 * its views. When adding a value that doesn't satisfy the predicate, the 1890 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 1891 * methods throw an {@link IllegalArgumentException}. 1892 * 1893 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 1894 * the filtered multimap or its views, only mappings whose value satisfy the 1895 * filter will be removed from the underlying multimap. 1896 * 1897 * <p>The returned multimap isn't threadsafe or serializable, even if 1898 * {@code unfiltered} is. 1899 * 1900 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 1901 * across every key/value mapping in the underlying multimap and determine 1902 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1903 * faster to copy the filtered multimap and use the copy. 1904 * 1905 * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 1906 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 1907 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 1908 * inconsistent with equals. 1909 * 1910 * @since 11.0 1911 */ 1912 @CheckReturnValue 1913 public static <K, V> Multimap<K, V> filterValues( 1914 Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 1915 return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate)); 1916 } 1917 1918 /** 1919 * Returns a multimap containing the mappings in {@code unfiltered} whose values 1920 * satisfy a predicate. The returned multimap is a live view of 1921 * {@code unfiltered}; changes to one affect the other. 1922 * 1923 * <p>The resulting multimap's views have iterators that don't support 1924 * {@code remove()}, but all other methods are supported by the multimap and 1925 * its views. When adding a value that doesn't satisfy the predicate, the 1926 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 1927 * methods throw an {@link IllegalArgumentException}. 1928 * 1929 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 1930 * the filtered multimap or its views, only mappings whose value satisfy the 1931 * filter will be removed from the underlying multimap. 1932 * 1933 * <p>The returned multimap isn't threadsafe or serializable, even if 1934 * {@code unfiltered} is. 1935 * 1936 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 1937 * across every key/value mapping in the underlying multimap and determine 1938 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1939 * faster to copy the filtered multimap and use the copy. 1940 * 1941 * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 1942 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 1943 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 1944 * inconsistent with equals. 1945 * 1946 * @since 14.0 1947 */ 1948 @CheckReturnValue 1949 public static <K, V> SetMultimap<K, V> filterValues( 1950 SetMultimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 1951 return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate)); 1952 } 1953 1954 /** 1955 * Returns a multimap containing the mappings in {@code unfiltered} that 1956 * satisfy a predicate. The returned multimap is a live view of 1957 * {@code unfiltered}; changes to one affect the other. 1958 * 1959 * <p>The resulting multimap's views have iterators that don't support 1960 * {@code remove()}, but all other methods are supported by the multimap and 1961 * its views. When adding a key/value pair that doesn't satisfy the predicate, 1962 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 1963 * methods throw an {@link IllegalArgumentException}. 1964 * 1965 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 1966 * the filtered multimap or its views, only mappings whose keys satisfy the 1967 * filter will be removed from the underlying multimap. 1968 * 1969 * <p>The returned multimap isn't threadsafe or serializable, even if 1970 * {@code unfiltered} is. 1971 * 1972 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 1973 * across every key/value mapping in the underlying multimap and determine 1974 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 1975 * faster to copy the filtered multimap and use the copy. 1976 * 1977 * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 1978 * equals</i>, as documented at {@link Predicate#apply}. 1979 * 1980 * @since 11.0 1981 */ 1982 @CheckReturnValue 1983 public static <K, V> Multimap<K, V> filterEntries( 1984 Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 1985 checkNotNull(entryPredicate); 1986 if (unfiltered instanceof SetMultimap) { 1987 return filterEntries((SetMultimap<K, V>) unfiltered, entryPredicate); 1988 } 1989 return (unfiltered instanceof FilteredMultimap) 1990 ? filterFiltered((FilteredMultimap<K, V>) unfiltered, entryPredicate) 1991 : new FilteredEntryMultimap<K, V>(checkNotNull(unfiltered), entryPredicate); 1992 } 1993 1994 /** 1995 * Returns a multimap containing the mappings in {@code unfiltered} that 1996 * satisfy a predicate. The returned multimap is a live view of 1997 * {@code unfiltered}; changes to one affect the other. 1998 * 1999 * <p>The resulting multimap's views have iterators that don't support 2000 * {@code remove()}, but all other methods are supported by the multimap and 2001 * its views. When adding a key/value pair that doesn't satisfy the predicate, 2002 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 2003 * methods throw an {@link IllegalArgumentException}. 2004 * 2005 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 2006 * the filtered multimap or its views, only mappings whose keys satisfy the 2007 * filter will be removed from the underlying multimap. 2008 * 2009 * <p>The returned multimap isn't threadsafe or serializable, even if 2010 * {@code unfiltered} is. 2011 * 2012 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 2013 * across every key/value mapping in the underlying multimap and determine 2014 * which satisfy the filter. When a live view is <i>not</i> needed, it may be 2015 * faster to copy the filtered multimap and use the copy. 2016 * 2017 * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 2018 * equals</i>, as documented at {@link Predicate#apply}. 2019 * 2020 * @since 14.0 2021 */ 2022 @CheckReturnValue 2023 public static <K, V> SetMultimap<K, V> filterEntries( 2024 SetMultimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 2025 checkNotNull(entryPredicate); 2026 return (unfiltered instanceof FilteredSetMultimap) 2027 ? filterFiltered((FilteredSetMultimap<K, V>) unfiltered, entryPredicate) 2028 : new FilteredEntrySetMultimap<K, V>(checkNotNull(unfiltered), entryPredicate); 2029 } 2030 2031 /** 2032 * Support removal operations when filtering a filtered multimap. Since a 2033 * filtered multimap has iterators that don't support remove, passing one to 2034 * the FilteredEntryMultimap constructor would lead to a multimap whose removal 2035 * operations would fail. This method combines the predicates to avoid that 2036 * problem. 2037 */ 2038 private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> multimap, 2039 Predicate<? super Entry<K, V>> entryPredicate) { 2040 Predicate<Entry<K, V>> predicate 2041 = Predicates.and(multimap.entryPredicate(), entryPredicate); 2042 return new FilteredEntryMultimap<K, V>(multimap.unfiltered(), predicate); 2043 } 2044 2045 /** 2046 * Support removal operations when filtering a filtered multimap. Since a filtered multimap has 2047 * iterators that don't support remove, passing one to the FilteredEntryMultimap constructor would 2048 * lead to a multimap whose removal operations would fail. This method combines the predicates to 2049 * avoid that problem. 2050 */ 2051 private static <K, V> SetMultimap<K, V> filterFiltered( 2052 FilteredSetMultimap<K, V> multimap, 2053 Predicate<? super Entry<K, V>> entryPredicate) { 2054 Predicate<Entry<K, V>> predicate 2055 = Predicates.and(multimap.entryPredicate(), entryPredicate); 2056 return new FilteredEntrySetMultimap<K, V>(multimap.unfiltered(), predicate); 2057 } 2058 2059 static boolean equalsImpl(Multimap<?, ?> multimap, @Nullable Object object) { 2060 if (object == multimap) { 2061 return true; 2062 } 2063 if (object instanceof Multimap) { 2064 Multimap<?, ?> that = (Multimap<?, ?>) object; 2065 return multimap.asMap().equals(that.asMap()); 2066 } 2067 return false; 2068 } 2069 2070 // TODO(jlevy): Create methods that filter a SortedSetMultimap. 2071}