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