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