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