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