001/* 002 * Copyright (C) 2008 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.Preconditions.checkState; 021import static com.google.common.collect.CollectPreconditions.checkEntryNotNull; 022import static com.google.common.collect.CollectPreconditions.checkNonnegative; 023import static com.google.common.collect.Maps.equalsImpl; 024import static com.google.common.collect.Maps.toStringImpl; 025import static com.google.common.collect.Sets.hashCodeImpl; 026import static java.lang.System.arraycopy; 027import static java.util.Arrays.sort; 028import static java.util.Objects.requireNonNull; 029 030import com.google.common.annotations.GwtCompatible; 031import com.google.common.annotations.GwtIncompatible; 032import com.google.common.annotations.J2ktIncompatible; 033import com.google.common.annotations.VisibleForTesting; 034import com.google.errorprone.annotations.CanIgnoreReturnValue; 035import com.google.errorprone.annotations.DoNotCall; 036import com.google.errorprone.annotations.DoNotMock; 037import com.google.errorprone.annotations.concurrent.LazyInit; 038import com.google.j2objc.annotations.RetainedWith; 039import java.io.InvalidObjectException; 040import java.io.ObjectInputStream; 041import java.io.Serializable; 042import java.util.Arrays; 043import java.util.BitSet; 044import java.util.Collection; 045import java.util.Collections; 046import java.util.Comparator; 047import java.util.EnumMap; 048import java.util.HashSet; 049import java.util.Iterator; 050import java.util.Map; 051import java.util.Set; 052import java.util.SortedMap; 053import java.util.Spliterator; 054import java.util.Spliterators; 055import java.util.function.BiFunction; 056import java.util.function.BinaryOperator; 057import java.util.function.Function; 058import java.util.stream.Collector; 059import java.util.stream.Collectors; 060import org.jspecify.annotations.Nullable; 061 062/** 063 * A {@link Map} whose contents will never change, with many other important properties detailed at 064 * {@link ImmutableCollection}. 065 * 066 * <p>See the Guava User Guide article on <a href= 067 * "https://github.com/google/guava/wiki/ImmutableCollectionsExplained">immutable collections</a>. 068 * 069 * @author Jesse Wilson 070 * @author Kevin Bourrillion 071 * @since 2.0 072 */ 073@DoNotMock("Use ImmutableMap.of or another implementation") 074@GwtCompatible 075@SuppressWarnings({ 076 "serial", // we're overriding default serialization 077 "TooManyParameters", 078}) 079public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable { 080 081 /** 082 * Returns a {@link Collector} that accumulates elements into an {@code ImmutableMap} whose keys 083 * and values are the result of applying the provided mapping functions to the input elements. 084 * Entries appear in the result {@code ImmutableMap} in encounter order. 085 * 086 * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}, an {@code 087 * IllegalArgumentException} is thrown when the collection operation is performed. (This differs 088 * from the {@code Collector} returned by {@link Collectors#toMap(Function, Function)}, which 089 * throws an {@code IllegalStateException}.) 090 * 091 * @since 21.0 092 */ 093 public static <T extends @Nullable Object, K, V> 094 Collector<T, ?, ImmutableMap<K, V>> toImmutableMap( 095 Function<? super T, ? extends K> keyFunction, 096 Function<? super T, ? extends V> valueFunction) { 097 return CollectCollectors.toImmutableMap(keyFunction, valueFunction); 098 } 099 100 /** 101 * Returns a {@link Collector} that accumulates elements into an {@code ImmutableMap} whose keys 102 * and values are the result of applying the provided mapping functions to the input elements. 103 * 104 * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}), the 105 * values are merged using the specified merging function. If the merging function returns {@code 106 * null}, then the collector removes the value that has been computed for the key thus far (though 107 * future occurrences of the key would reinsert it). 108 * 109 * <p>Entries will appear in the encounter order of the first occurrence of the key. 110 * 111 * @since 21.0 112 */ 113 public static <T extends @Nullable Object, K, V> 114 Collector<T, ?, ImmutableMap<K, V>> toImmutableMap( 115 Function<? super T, ? extends K> keyFunction, 116 Function<? super T, ? extends V> valueFunction, 117 BinaryOperator<V> mergeFunction) { 118 return CollectCollectors.toImmutableMap(keyFunction, valueFunction, mergeFunction); 119 } 120 121 /** 122 * Returns the empty map. This map behaves and performs comparably to {@link 123 * Collections#emptyMap}, and is preferable mainly for consistency and maintainability of your 124 * code. 125 * 126 * <p><b>Performance note:</b> the instance returned is a singleton. 127 */ 128 @SuppressWarnings("unchecked") 129 public static <K, V> ImmutableMap<K, V> of() { 130 return (ImmutableMap<K, V>) RegularImmutableMap.EMPTY; 131 } 132 133 /** 134 * Returns an immutable map containing a single entry. This map behaves and performs comparably to 135 * {@link Collections#singletonMap} but will not accept a null key or value. It is preferable 136 * mainly for consistency and maintainability of your code. 137 */ 138 public static <K, V> ImmutableMap<K, V> of(K k1, V v1) { 139 return ImmutableBiMap.of(k1, v1); 140 } 141 142 /** 143 * Returns an immutable map containing the given entries, in order. 144 * 145 * @throws IllegalArgumentException if duplicate keys are provided 146 */ 147 public static <K, V> ImmutableMap<K, V> of(K k1, V v1, K k2, V v2) { 148 return RegularImmutableMap.fromEntries(entryOf(k1, v1), entryOf(k2, v2)); 149 } 150 151 /** 152 * Returns an immutable map containing the given entries, in order. 153 * 154 * @throws IllegalArgumentException if duplicate keys are provided 155 */ 156 public static <K, V> ImmutableMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) { 157 return RegularImmutableMap.fromEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3)); 158 } 159 160 /** 161 * Returns an immutable map containing the given entries, in order. 162 * 163 * @throws IllegalArgumentException if duplicate keys are provided 164 */ 165 public static <K, V> ImmutableMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { 166 return RegularImmutableMap.fromEntries( 167 entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4)); 168 } 169 170 /** 171 * Returns an immutable map containing the given entries, in order. 172 * 173 * @throws IllegalArgumentException if duplicate keys are provided 174 */ 175 public static <K, V> ImmutableMap<K, V> of( 176 K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { 177 return RegularImmutableMap.fromEntries( 178 entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5)); 179 } 180 181 /** 182 * Returns an immutable map containing the given entries, in order. 183 * 184 * @throws IllegalArgumentException if duplicate keys are provided 185 * @since 31.0 186 */ 187 public static <K, V> ImmutableMap<K, V> of( 188 K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { 189 return RegularImmutableMap.fromEntries( 190 entryOf(k1, v1), 191 entryOf(k2, v2), 192 entryOf(k3, v3), 193 entryOf(k4, v4), 194 entryOf(k5, v5), 195 entryOf(k6, v6)); 196 } 197 198 /** 199 * Returns an immutable map containing the given entries, in order. 200 * 201 * @throws IllegalArgumentException if duplicate keys are provided 202 * @since 31.0 203 */ 204 public static <K, V> ImmutableMap<K, V> of( 205 K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { 206 return RegularImmutableMap.fromEntries( 207 entryOf(k1, v1), 208 entryOf(k2, v2), 209 entryOf(k3, v3), 210 entryOf(k4, v4), 211 entryOf(k5, v5), 212 entryOf(k6, v6), 213 entryOf(k7, v7)); 214 } 215 216 /** 217 * Returns an immutable map containing the given entries, in order. 218 * 219 * @throws IllegalArgumentException if duplicate keys are provided 220 * @since 31.0 221 */ 222 public static <K, V> ImmutableMap<K, V> of( 223 K k1, 224 V v1, 225 K k2, 226 V v2, 227 K k3, 228 V v3, 229 K k4, 230 V v4, 231 K k5, 232 V v5, 233 K k6, 234 V v6, 235 K k7, 236 V v7, 237 K k8, 238 V v8) { 239 return RegularImmutableMap.fromEntries( 240 entryOf(k1, v1), 241 entryOf(k2, v2), 242 entryOf(k3, v3), 243 entryOf(k4, v4), 244 entryOf(k5, v5), 245 entryOf(k6, v6), 246 entryOf(k7, v7), 247 entryOf(k8, v8)); 248 } 249 250 /** 251 * Returns an immutable map containing the given entries, in order. 252 * 253 * @throws IllegalArgumentException if duplicate keys are provided 254 * @since 31.0 255 */ 256 public static <K, V> ImmutableMap<K, V> of( 257 K k1, 258 V v1, 259 K k2, 260 V v2, 261 K k3, 262 V v3, 263 K k4, 264 V v4, 265 K k5, 266 V v5, 267 K k6, 268 V v6, 269 K k7, 270 V v7, 271 K k8, 272 V v8, 273 K k9, 274 V v9) { 275 return RegularImmutableMap.fromEntries( 276 entryOf(k1, v1), 277 entryOf(k2, v2), 278 entryOf(k3, v3), 279 entryOf(k4, v4), 280 entryOf(k5, v5), 281 entryOf(k6, v6), 282 entryOf(k7, v7), 283 entryOf(k8, v8), 284 entryOf(k9, v9)); 285 } 286 287 /** 288 * Returns an immutable map containing the given entries, in order. 289 * 290 * @throws IllegalArgumentException if duplicate keys are provided 291 * @since 31.0 292 */ 293 public static <K, V> ImmutableMap<K, V> of( 294 K k1, 295 V v1, 296 K k2, 297 V v2, 298 K k3, 299 V v3, 300 K k4, 301 V v4, 302 K k5, 303 V v5, 304 K k6, 305 V v6, 306 K k7, 307 V v7, 308 K k8, 309 V v8, 310 K k9, 311 V v9, 312 K k10, 313 V v10) { 314 return RegularImmutableMap.fromEntries( 315 entryOf(k1, v1), 316 entryOf(k2, v2), 317 entryOf(k3, v3), 318 entryOf(k4, v4), 319 entryOf(k5, v5), 320 entryOf(k6, v6), 321 entryOf(k7, v7), 322 entryOf(k8, v8), 323 entryOf(k9, v9), 324 entryOf(k10, v10)); 325 } 326 327 // looking for of() with > 10 entries? Use the builder or ofEntries instead. 328 329 /** 330 * Returns an immutable map containing the given entries, in order. 331 * 332 * @throws IllegalArgumentException if duplicate keys are provided 333 * @since 31.0 334 */ 335 @SafeVarargs 336 public static <K, V> ImmutableMap<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) { 337 @SuppressWarnings("unchecked") // we will only ever read these 338 Entry<K, V>[] entries2 = (Entry<K, V>[]) entries; 339 return RegularImmutableMap.fromEntries(entries2); 340 } 341 342 /** 343 * Verifies that {@code key} and {@code value} are non-null, and returns a new immutable entry 344 * with those values. 345 * 346 * <p>A call to {@link Entry#setValue} on the returned entry will always throw {@link 347 * UnsupportedOperationException}. 348 */ 349 static <K, V> Entry<K, V> entryOf(K key, V value) { 350 return new ImmutableMapEntry<>(key, value); 351 } 352 353 /** 354 * Returns a new builder. The generated builder is equivalent to the builder created by the {@link 355 * Builder} constructor. 356 */ 357 public static <K, V> Builder<K, V> builder() { 358 return new Builder<>(); 359 } 360 361 /** 362 * Returns a new builder, expecting the specified number of entries to be added. 363 * 364 * <p>If {@code expectedSize} is exactly the number of entries added to the builder before {@link 365 * Builder#build} is called, the builder is likely to perform better than an unsized {@link 366 * #builder()} would have. 367 * 368 * <p>It is not specified if any performance benefits apply if {@code expectedSize} is close to, 369 * but not exactly, the number of entries added to the builder. 370 * 371 * @since 23.1 372 */ 373 public static <K, V> Builder<K, V> builderWithExpectedSize(int expectedSize) { 374 checkNonnegative(expectedSize, "expectedSize"); 375 return new Builder<>(expectedSize); 376 } 377 378 static void checkNoConflict( 379 boolean safe, String conflictDescription, Object entry1, Object entry2) { 380 if (!safe) { 381 throw conflictException(conflictDescription, entry1, entry2); 382 } 383 } 384 385 static IllegalArgumentException conflictException( 386 String conflictDescription, Object entry1, Object entry2) { 387 return new IllegalArgumentException( 388 "Multiple entries with same " + conflictDescription + ": " + entry1 + " and " + entry2); 389 } 390 391 /** 392 * A builder for creating immutable map instances, especially {@code public static final} maps 393 * ("constant maps"). Example: 394 * 395 * {@snippet : 396 * static final ImmutableMap<String, Integer> WORD_TO_INT = 397 * new ImmutableMap.Builder<String, Integer>() 398 * .put("one", 1) 399 * .put("two", 2) 400 * .put("three", 3) 401 * .buildOrThrow(); 402 * } 403 * 404 * <p>For <i>small</i> immutable maps, the {@code ImmutableMap.of()} methods are even more 405 * convenient. 406 * 407 * <p>By default, a {@code Builder} will generate maps that iterate over entries in the order they 408 * were inserted into the builder, equivalently to {@code LinkedHashMap}. For example, in the 409 * above example, {@code WORD_TO_INT.entrySet()} is guaranteed to iterate over the entries in the 410 * order {@code "one"=1, "two"=2, "three"=3}, and {@code keySet()} and {@code values()} respect 411 * the same order. If you want a different order, consider using {@link ImmutableSortedMap} to 412 * sort by keys, or call {@link #orderEntriesByValue(Comparator)}, which changes this builder to 413 * sort entries by value. 414 * 415 * <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to 416 * build multiple maps in series. Each map is a superset of the maps created before it. 417 * 418 * @since 2.0 419 */ 420 @DoNotMock 421 public static class Builder<K, V> { 422 @Nullable Comparator<? super V> valueComparator; 423 @Nullable Entry<K, V>[] entries; 424 int size; 425 boolean entriesUsed; 426 427 /** 428 * Creates a new builder. The returned builder is equivalent to the builder generated by {@link 429 * ImmutableMap#builder}. 430 */ 431 public Builder() { 432 this(ImmutableCollection.Builder.DEFAULT_INITIAL_CAPACITY); 433 } 434 435 @SuppressWarnings({"unchecked", "rawtypes"}) 436 Builder(int initialCapacity) { 437 this.entries = new @Nullable Entry[initialCapacity]; 438 this.size = 0; 439 this.entriesUsed = false; 440 } 441 442 private void ensureCapacity(int minCapacity) { 443 if (minCapacity > entries.length) { 444 entries = 445 Arrays.copyOf( 446 entries, ImmutableCollection.Builder.expandedCapacity(entries.length, minCapacity)); 447 entriesUsed = false; 448 } 449 } 450 451 /** 452 * Associates {@code key} with {@code value} in the built map. If the same key is put more than 453 * once, {@link #buildOrThrow} will fail, while {@link #buildKeepingLast} will keep the last 454 * value put for that key. 455 */ 456 @CanIgnoreReturnValue 457 public Builder<K, V> put(K key, V value) { 458 ensureCapacity(size + 1); 459 Entry<K, V> entry = entryOf(key, value); 460 // don't inline this: we want to fail atomically if key or value is null 461 entries[size++] = entry; 462 return this; 463 } 464 465 /** 466 * Adds the given {@code entry} to the map, making it immutable if necessary. If the same key is 467 * put more than once, {@link #buildOrThrow} will fail, while {@link #buildKeepingLast} will 468 * keep the last value put for that key. 469 * 470 * @since 11.0 471 */ 472 @CanIgnoreReturnValue 473 public Builder<K, V> put(Entry<? extends K, ? extends V> entry) { 474 return put(entry.getKey(), entry.getValue()); 475 } 476 477 /** 478 * Associates all of the given map's keys and values in the built map. If the same key is put 479 * more than once, {@link #buildOrThrow} will fail, while {@link #buildKeepingLast} will keep 480 * the last value put for that key. 481 * 482 * @throws NullPointerException if any key or value in {@code map} is null 483 */ 484 @CanIgnoreReturnValue 485 public Builder<K, V> putAll(Map<? extends K, ? extends V> map) { 486 return putAll(map.entrySet()); 487 } 488 489 /** 490 * Adds all of the given entries to the built map. If the same key is put more than once, {@link 491 * #buildOrThrow} will fail, while {@link #buildKeepingLast} will keep the last value put for 492 * that key. 493 * 494 * @throws NullPointerException if any key, value, or entry is null 495 * @since 19.0 496 */ 497 @CanIgnoreReturnValue 498 public Builder<K, V> putAll(Iterable<? extends Entry<? extends K, ? extends V>> entries) { 499 if (entries instanceof Collection) { 500 ensureCapacity(size + ((Collection<?>) entries).size()); 501 } 502 for (Entry<? extends K, ? extends V> entry : entries) { 503 put(entry); 504 } 505 return this; 506 } 507 508 /** 509 * Configures this {@code Builder} to order entries by value according to the specified 510 * comparator. 511 * 512 * <p>The sort order is stable, that is, if two entries have values that compare as equivalent, 513 * the entry that was inserted first will be first in the built map's iteration order. 514 * 515 * @throws IllegalStateException if this method was already called 516 * @since 19.0 517 */ 518 @CanIgnoreReturnValue 519 public Builder<K, V> orderEntriesByValue(Comparator<? super V> valueComparator) { 520 checkState(this.valueComparator == null, "valueComparator was already set"); 521 this.valueComparator = checkNotNull(valueComparator, "valueComparator"); 522 return this; 523 } 524 525 @CanIgnoreReturnValue 526 Builder<K, V> combine(Builder<K, V> other) { 527 checkNotNull(other); 528 ensureCapacity(this.size + other.size); 529 arraycopy(other.entries, 0, this.entries, this.size, other.size); 530 this.size += other.size; 531 return this; 532 } 533 534 private ImmutableMap<K, V> build(boolean throwIfDuplicateKeys) { 535 /* 536 * If entries is full, or if hash flooding is detected, then this implementation may end up 537 * using the entries array directly and writing over the entry objects with non-terminal 538 * entries, but this is safe; if this Builder is used further, it will grow the entries array 539 * (so it can't affect the original array), and future build() calls will always copy any 540 * entry objects that cannot be safely reused. 541 */ 542 switch (size) { 543 case 0: 544 return of(); 545 case 1: 546 // requireNonNull is safe because the first `size` elements have been filled in. 547 Entry<K, V> onlyEntry = requireNonNull(entries[0]); 548 return of(onlyEntry.getKey(), onlyEntry.getValue()); 549 default: 550 break; 551 } 552 // localEntries is an alias for the entries field, except if we end up removing duplicates in 553 // a copy of the entries array. Likewise, localSize is the same as size except in that case. 554 // It's possible to keep using this Builder after calling buildKeepingLast(), so we need to 555 // ensure that its state is not corrupted by removing duplicates that should cause a later 556 // buildOrThrow() to fail, or by changing the size. 557 @Nullable Entry<K, V>[] localEntries; 558 int localSize = size; 559 if (valueComparator == null) { 560 localEntries = entries; 561 } else { 562 if (entriesUsed) { 563 entries = Arrays.copyOf(entries, size); 564 } 565 @SuppressWarnings("nullness") // entries 0..localSize-1 are non-null 566 Entry<K, V>[] nonNullEntries = entries; 567 if (!throwIfDuplicateKeys) { 568 // We want to retain only the last-put value for any given key, before sorting. 569 // This could be improved, but orderEntriesByValue is rather rarely used anyway. 570 Entry<K, V>[] lastEntryForEachKey = lastEntryForEachKey(nonNullEntries, size); 571 if (lastEntryForEachKey != null) { 572 nonNullEntries = lastEntryForEachKey; 573 localSize = lastEntryForEachKey.length; 574 } 575 } 576 sort( 577 nonNullEntries, 578 0, 579 localSize, 580 Ordering.from(valueComparator).onResultOf(Entry::getValue)); 581 localEntries = nonNullEntries; 582 } 583 entriesUsed = true; 584 return RegularImmutableMap.fromEntryArray(localSize, localEntries, throwIfDuplicateKeys); 585 } 586 587 /** 588 * Returns a newly-created immutable map. The iteration order of the returned map is the order 589 * in which entries were inserted into the builder, unless {@link #orderEntriesByValue} was 590 * called, in which case entries are sorted by value. 591 * 592 * <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method 593 * will throw an exception if there are duplicate keys. The {@code build()} method will soon be 594 * deprecated. 595 * 596 * @throws IllegalArgumentException if duplicate keys were added 597 */ 598 public ImmutableMap<K, V> build() { 599 return buildOrThrow(); 600 } 601 602 /** 603 * Returns a newly-created immutable map, or throws an exception if any key was added more than 604 * once. The iteration order of the returned map is the order in which entries were inserted 605 * into the builder, unless {@link #orderEntriesByValue} was called, in which case entries are 606 * sorted by value. 607 * 608 * @throws IllegalArgumentException if duplicate keys were added 609 * @since 31.0 610 */ 611 public ImmutableMap<K, V> buildOrThrow() { 612 return build(true); 613 } 614 615 /** 616 * Returns a newly-created immutable map, using the last value for any key that was added more 617 * than once. The iteration order of the returned map is the order in which entries were 618 * inserted into the builder, unless {@link #orderEntriesByValue} was called, in which case 619 * entries are sorted by value. If a key was added more than once, it appears in iteration order 620 * based on the first time it was added, again unless {@link #orderEntriesByValue} was called. 621 * 622 * <p>In the current implementation, all values associated with a given key are stored in the 623 * {@code Builder} object, even though only one of them will be used in the built map. If there 624 * can be many repeated keys, it may be more space-efficient to use a {@link 625 * java.util.LinkedHashMap LinkedHashMap} and {@link ImmutableMap#copyOf(Map)} rather than 626 * {@code ImmutableMap.Builder}. 627 * 628 * @since 31.1 629 */ 630 public ImmutableMap<K, V> buildKeepingLast() { 631 return build(false); 632 } 633 634 @VisibleForTesting // only for testing JDK backed implementation 635 ImmutableMap<K, V> buildJdkBacked() { 636 checkState( 637 valueComparator == null, "buildJdkBacked is only for testing; can't use valueComparator"); 638 switch (size) { 639 case 0: 640 return of(); 641 case 1: 642 // requireNonNull is safe because the first `size` elements have been filled in. 643 Entry<K, V> onlyEntry = requireNonNull(entries[0]); 644 return of(onlyEntry.getKey(), onlyEntry.getValue()); 645 default: 646 entriesUsed = true; 647 return JdkBackedImmutableMap.create(size, entries, /* throwIfDuplicateKeys= */ true); 648 } 649 } 650 651 /** 652 * Scans the first {@code size} elements of {@code entries} looking for duplicate keys. If 653 * duplicates are found, a new correctly-sized array is returned with the same elements (up to 654 * {@code size}), except containing only the last occurrence of each duplicate key. Otherwise 655 * {@code null} is returned. 656 */ 657 private static <K, V> Entry<K, V> @Nullable [] lastEntryForEachKey( 658 Entry<K, V>[] entries, int size) { 659 Set<K> seen = new HashSet<>(); 660 BitSet dups = new BitSet(); // slots that are overridden by a later duplicate key 661 for (int i = size - 1; i >= 0; i--) { 662 if (!seen.add(entries[i].getKey())) { 663 dups.set(i); 664 } 665 } 666 if (dups.isEmpty()) { 667 return null; 668 } 669 @SuppressWarnings({"rawtypes", "unchecked"}) 670 Entry<K, V>[] newEntries = new Entry[size - dups.cardinality()]; 671 for (int inI = 0, outI = 0; inI < size; inI++) { 672 if (!dups.get(inI)) { 673 newEntries[outI++] = entries[inI]; 674 } 675 } 676 return newEntries; 677 } 678 } 679 680 /** 681 * Returns an immutable map containing the same entries as {@code map}. The returned map iterates 682 * over entries in the same order as the {@code entrySet} of the original map. If {@code map} 683 * somehow contains entries with duplicate keys (for example, if it is a {@code SortedMap} whose 684 * comparator is not <i>consistent with equals</i>), the results of this method are undefined. 685 * 686 * <p>Despite the method name, this method attempts to avoid actually copying the data when it is 687 * safe to do so. The exact circumstances under which a copy will or will not be performed are 688 * undocumented and subject to change. 689 * 690 * @throws NullPointerException if any key or value in {@code map} is null 691 */ 692 public static <K, V> ImmutableMap<K, V> copyOf(Map<? extends K, ? extends V> map) { 693 if ((map instanceof ImmutableMap) && !(map instanceof SortedMap)) { 694 @SuppressWarnings("unchecked") // safe since map is not writable 695 ImmutableMap<K, V> kvMap = (ImmutableMap<K, V>) map; 696 if (!kvMap.isPartialView()) { 697 return kvMap; 698 } 699 } else if (map instanceof EnumMap) { 700 EnumMap<?, ? extends V> clone = ((EnumMap<?, ? extends V>) map).clone(); 701 for (Entry<?, ?> entry : clone.entrySet()) { 702 checkEntryNotNull(entry.getKey(), entry.getValue()); 703 } 704 ImmutableMap<?, ? extends V> untypedResult = ImmutableEnumMap.asImmutable(clone); 705 /* 706 * The result has the same type argument we started with. We just couldn't express EnumMap<K, 707 * ...> or ImmutableEnumMap<K, ...> along the way because our own <K> isn't <K extends 708 * Enum<K>>. 709 * 710 * We are also performing a covariant cast, potentially from ImmutableMap<K, Sub> to 711 * ImmutableMap<K, Super>. That is safe because no one can add elements to the map. 712 */ 713 @SuppressWarnings("unchecked") 714 ImmutableMap<K, V> result = (ImmutableMap<K, V>) untypedResult; 715 return result; 716 } 717 return copyOf(map.entrySet()); 718 } 719 720 /** 721 * Returns an immutable map containing the specified entries. The returned map iterates over 722 * entries in the same order as the original iterable. 723 * 724 * @throws NullPointerException if any key, value, or entry is null 725 * @throws IllegalArgumentException if two entries have the same key 726 * @since 19.0 727 */ 728 public static <K, V> ImmutableMap<K, V> copyOf( 729 Iterable<? extends Entry<? extends K, ? extends V>> entries) { 730 @SuppressWarnings("unchecked") // we'll only be using getKey and getValue, which are covariant 731 Entry<K, V>[] entryArray = (Entry<K, V>[]) Iterables.toArray(entries, EMPTY_ENTRY_ARRAY); 732 switch (entryArray.length) { 733 case 0: 734 return of(); 735 case 1: 736 // requireNonNull is safe because the first `size` elements have been filled in. 737 Entry<K, V> onlyEntry = requireNonNull(entryArray[0]); 738 return of(onlyEntry.getKey(), onlyEntry.getValue()); 739 default: 740 /* 741 * The current implementation will end up using entryArray directly, though it will write 742 * over the (arbitrary, potentially mutable) Entry objects actually stored in entryArray. 743 */ 744 return RegularImmutableMap.fromEntries(entryArray); 745 } 746 } 747 748 static final Entry<?, ?>[] EMPTY_ENTRY_ARRAY = new Entry<?, ?>[0]; 749 750 abstract static class IteratorBasedImmutableMap<K, V> extends ImmutableMap<K, V> { 751 abstract UnmodifiableIterator<Entry<K, V>> entryIterator(); 752 753 @GwtIncompatible // Spliterator 754 Spliterator<Entry<K, V>> entrySpliterator() { 755 return Spliterators.spliterator( 756 entryIterator(), 757 size(), 758 Spliterator.DISTINCT | Spliterator.NONNULL | Spliterator.IMMUTABLE | Spliterator.ORDERED); 759 } 760 761 @LazyInit @RetainedWith private transient @Nullable ImmutableSet<Entry<K, V>> entrySet; 762 763 @Override 764 public final ImmutableSet<Entry<K, V>> entrySet() { 765 ImmutableSet<Entry<K, V>> result = entrySet; 766 if (result == null) { 767 result = entrySet = createEntrySet(); 768 } 769 return result; 770 } 771 772 final ImmutableSet<Entry<K, V>> createEntrySet() { 773 final class EntrySetImpl extends ImmutableMapEntrySet<K, V> { 774 @Override 775 ImmutableMap<K, V> map() { 776 return IteratorBasedImmutableMap.this; 777 } 778 779 @Override 780 public UnmodifiableIterator<Entry<K, V>> iterator() { 781 return entryIterator(); 782 } 783 784 @Override 785 public Spliterator<Entry<K, V>> spliterator() { 786 return IteratorBasedImmutableMap.this.entrySpliterator(); 787 } 788 789 // redeclare to help optimizers with b/310253115 790 @SuppressWarnings("RedundantOverride") 791 @Override 792 @J2ktIncompatible 793 @GwtIncompatible 794 Object writeReplace() { 795 return super.writeReplace(); 796 } 797 } 798 return new EntrySetImpl(); 799 } 800 801 @LazyInit @RetainedWith private transient @Nullable ImmutableSet<K> keySet; 802 803 @Override 804 public final ImmutableSet<K> keySet() { 805 ImmutableSet<K> result = keySet; 806 if (result == null) { 807 result = keySet = createKeySet(); 808 } 809 return result; 810 } 811 812 ImmutableSet<K> createKeySet() { 813 return new ImmutableMapKeySet<>(this); 814 } 815 816 @LazyInit @RetainedWith private transient @Nullable ImmutableCollection<V> values; 817 818 @Override 819 public final ImmutableCollection<V> values() { 820 ImmutableCollection<V> result = values; 821 if (result == null) { 822 result = values = createValues(); 823 } 824 return result; 825 } 826 827 final ImmutableCollection<V> createValues() { 828 return new ImmutableMapValues<>(this); 829 } 830 831 // redeclare to help optimizers with b/310253115 832 @SuppressWarnings("RedundantOverride") 833 @Override 834 @J2ktIncompatible 835 @GwtIncompatible 836 Object writeReplace() { 837 return super.writeReplace(); 838 } 839 } 840 841 ImmutableMap() {} 842 843 /** 844 * Guaranteed to throw an exception and leave the map unmodified. 845 * 846 * @throws UnsupportedOperationException always 847 * @deprecated Unsupported operation. 848 */ 849 @CanIgnoreReturnValue 850 @Deprecated 851 @Override 852 @DoNotCall("Always throws UnsupportedOperationException") 853 public final @Nullable V put(K k, V v) { 854 throw new UnsupportedOperationException(); 855 } 856 857 /** 858 * Guaranteed to throw an exception and leave the map unmodified. 859 * 860 * @throws UnsupportedOperationException always 861 * @deprecated Unsupported operation. 862 */ 863 @CanIgnoreReturnValue 864 @Deprecated 865 @Override 866 @DoNotCall("Always throws UnsupportedOperationException") 867 public final @Nullable V putIfAbsent(K key, V value) { 868 throw new UnsupportedOperationException(); 869 } 870 871 /** 872 * Guaranteed to throw an exception and leave the map unmodified. 873 * 874 * @throws UnsupportedOperationException always 875 * @deprecated Unsupported operation. 876 */ 877 @Deprecated 878 @Override 879 @DoNotCall("Always throws UnsupportedOperationException") 880 public final boolean replace(K key, V oldValue, V newValue) { 881 throw new UnsupportedOperationException(); 882 } 883 884 /** 885 * Guaranteed to throw an exception and leave the map unmodified. 886 * 887 * @throws UnsupportedOperationException always 888 * @deprecated Unsupported operation. 889 */ 890 @Deprecated 891 @Override 892 @DoNotCall("Always throws UnsupportedOperationException") 893 public final @Nullable V replace(K key, V value) { 894 throw new UnsupportedOperationException(); 895 } 896 897 /** 898 * Guaranteed to throw an exception and leave the map unmodified. 899 * 900 * @throws UnsupportedOperationException always 901 * @deprecated Unsupported operation. 902 */ 903 @Deprecated 904 @Override 905 @DoNotCall("Always throws UnsupportedOperationException") 906 public final V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { 907 throw new UnsupportedOperationException(); 908 } 909 910 /** 911 * Guaranteed to throw an exception and leave the map unmodified. 912 * 913 * @throws UnsupportedOperationException always 914 * @deprecated Unsupported operation. 915 */ 916 @Deprecated 917 @Override 918 @DoNotCall("Always throws UnsupportedOperationException") 919 public final @Nullable V computeIfPresent( 920 K key, BiFunction<? super K, ? super V, ? extends @Nullable V> remappingFunction) { 921 throw new UnsupportedOperationException(); 922 } 923 924 /** 925 * Guaranteed to throw an exception and leave the map unmodified. 926 * 927 * @throws UnsupportedOperationException always 928 * @deprecated Unsupported operation. 929 */ 930 @Deprecated 931 @Override 932 @DoNotCall("Always throws UnsupportedOperationException") 933 public final @Nullable V compute( 934 K key, BiFunction<? super K, ? super @Nullable V, ? extends @Nullable V> remappingFunction) { 935 throw new UnsupportedOperationException(); 936 } 937 938 /** 939 * Guaranteed to throw an exception and leave the map unmodified. 940 * 941 * @throws UnsupportedOperationException always 942 * @deprecated Unsupported operation. 943 */ 944 @Deprecated 945 @Override 946 @DoNotCall("Always throws UnsupportedOperationException") 947 public final @Nullable V merge( 948 K key, V value, BiFunction<? super V, ? super V, ? extends @Nullable V> function) { 949 throw new UnsupportedOperationException(); 950 } 951 952 /** 953 * Guaranteed to throw an exception and leave the map unmodified. 954 * 955 * @throws UnsupportedOperationException always 956 * @deprecated Unsupported operation. 957 */ 958 @Deprecated 959 @Override 960 @DoNotCall("Always throws UnsupportedOperationException") 961 public final void putAll(Map<? extends K, ? extends V> map) { 962 throw new UnsupportedOperationException(); 963 } 964 965 /** 966 * Guaranteed to throw an exception and leave the map unmodified. 967 * 968 * @throws UnsupportedOperationException always 969 * @deprecated Unsupported operation. 970 */ 971 @Deprecated 972 @Override 973 @DoNotCall("Always throws UnsupportedOperationException") 974 public final void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { 975 throw new UnsupportedOperationException(); 976 } 977 978 /** 979 * Guaranteed to throw an exception and leave the map unmodified. 980 * 981 * @throws UnsupportedOperationException always 982 * @deprecated Unsupported operation. 983 */ 984 @Deprecated 985 @Override 986 @DoNotCall("Always throws UnsupportedOperationException") 987 public final @Nullable V remove(@Nullable Object o) { 988 throw new UnsupportedOperationException(); 989 } 990 991 /** 992 * Guaranteed to throw an exception and leave the map unmodified. 993 * 994 * @throws UnsupportedOperationException always 995 * @deprecated Unsupported operation. 996 */ 997 @Deprecated 998 @Override 999 @DoNotCall("Always throws UnsupportedOperationException") 1000 public final boolean remove(@Nullable Object key, @Nullable Object value) { 1001 throw new UnsupportedOperationException(); 1002 } 1003 1004 /** 1005 * Guaranteed to throw an exception and leave the map unmodified. 1006 * 1007 * @throws UnsupportedOperationException always 1008 * @deprecated Unsupported operation. 1009 */ 1010 @Deprecated 1011 @Override 1012 @DoNotCall("Always throws UnsupportedOperationException") 1013 public final void clear() { 1014 throw new UnsupportedOperationException(); 1015 } 1016 1017 @Override 1018 public final boolean isEmpty() { 1019 return size() == 0; 1020 } 1021 1022 @Override 1023 public boolean containsKey(@Nullable Object key) { 1024 return get(key) != null; 1025 } 1026 1027 @Override 1028 public boolean containsValue(@Nullable Object value) { 1029 return values().contains(value); 1030 } 1031 1032 // Overriding to mark it Nullable 1033 @Override 1034 public abstract @Nullable V get(@Nullable Object key); 1035 1036 /** 1037 * @since 21.0 (but only since 23.5 in the Android <a 1038 * href="https://github.com/google/guava#guava-google-core-libraries-for-java">flavor</a>). 1039 * Note, however, that Java 8+ users can call this method with any version and flavor of 1040 * Guava. 1041 */ 1042 @Override 1043 public final @Nullable V getOrDefault(@Nullable Object key, @Nullable V defaultValue) { 1044 /* 1045 * Even though it's weird to pass a defaultValue that is null, some callers do so. Those who 1046 * pass a literal "null" should probably just use `get`, but I would expect other callers to 1047 * pass an expression that *might* be null. This could happen with: 1048 * 1049 * - a `getFooOrDefault(@Nullable Foo defaultValue)` method that returns 1050 * `map.getOrDefault(FOO_KEY, defaultValue)` 1051 * 1052 * - a call that consults a chain of maps, as in `mapA.getOrDefault(key, mapB.getOrDefault(key, 1053 * ...))` 1054 * 1055 * So it makes sense for the parameter (and thus the return type) to be @Nullable. 1056 * 1057 * Two other points: 1058 * 1059 * 1. We'll want to use something like @PolyNull once we can make that work for the various 1060 * platforms we target. 1061 * 1062 * 2. Kotlin's Map type has a getOrDefault method that accepts and returns a "plain V," in 1063 * contrast to the "V?" type that we're using. As a result, Kotlin sees a conflict between the 1064 * nullness annotations in ImmutableMap and those in its own Map type. In response, it considers 1065 * the parameter and return type both to be platform types. As a result, Kotlin permits calls 1066 * that can lead to NullPointerException. That's unfortunate. But hopefully most Kotlin callers 1067 * use `get(key) ?: defaultValue` instead of this method, anyway. 1068 */ 1069 V result = get(key); 1070 // TODO(b/192579700): Use a ternary once it no longer confuses our nullness checker. 1071 if (result != null) { 1072 return result; 1073 } else { 1074 return defaultValue; 1075 } 1076 } 1077 1078 /** 1079 * Returns an immutable set of the mappings in this map. The iteration order is specified by the 1080 * method used to create this map. Typically, this is insertion order. 1081 */ 1082 @Override 1083 public abstract ImmutableSet<Entry<K, V>> entrySet(); 1084 1085 /** 1086 * Returns an immutable set of the keys in this map, in the same order that they appear in {@link 1087 * #entrySet}. 1088 */ 1089 /* 1090 * This could have a good default implementation of `return new ImmutableKeySet<K, V>(this)`, but 1091 * ProGuard can't figure out how to eliminate that default when RegularImmutableMap overrides it. 1092 */ 1093 @Override 1094 public abstract ImmutableSet<K> keySet(); 1095 1096 UnmodifiableIterator<K> keyIterator() { 1097 UnmodifiableIterator<Entry<K, V>> entryIterator = entrySet().iterator(); 1098 return new UnmodifiableIterator<K>() { 1099 @Override 1100 public boolean hasNext() { 1101 return entryIterator.hasNext(); 1102 } 1103 1104 @Override 1105 public K next() { 1106 return entryIterator.next().getKey(); 1107 } 1108 }; 1109 } 1110 1111 @GwtIncompatible // Spliterator 1112 Spliterator<K> keySpliterator() { 1113 return CollectSpliterators.map( 1114 entrySet().spliterator(), 1115 Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.NONNULL | Spliterator.IMMUTABLE, 1116 Entry::getKey); 1117 } 1118 1119 /** 1120 * Returns an immutable collection of the values in this map, in the same order that they appear 1121 * in {@link #entrySet}. 1122 */ 1123 /* 1124 * This could have a good default implementation of `return new ImmutableMapValues<K, V>(this)`, 1125 * but ProGuard can't figure out how to eliminate that default when RegularImmutableMap overrides 1126 * it. 1127 */ 1128 @Override 1129 public abstract ImmutableCollection<V> values(); 1130 1131 /** 1132 * Returns a multimap view of the map. 1133 * 1134 * <p>This method may return a new multimap instance on each call. While the multimap is cheap to 1135 * create, it is an instance of {@link ImmutableMultimap}, whose {@link ImmutableMultimap#inverse 1136 * inverse()} method may perform a more expensive operation and cache the result. Callers who want 1137 * to repeatedly operate on {@code map.asMultimap().inverse()} may wish to store the result of 1138 * that expression (or store the result of {@code asMultimap()}, since it caches its {@code 1139 * inverse()} view). 1140 * 1141 * @since 14.0 1142 */ 1143 public final ImmutableSetMultimap<K, V> asMultimap() { 1144 if (isEmpty()) { 1145 return ImmutableSetMultimap.of(); 1146 } 1147 return new ImmutableSetMultimap<>(new MapViewOfValuesAsSingletonSets(), size(), null); 1148 } 1149 1150 private final class MapViewOfValuesAsSingletonSets 1151 extends IteratorBasedImmutableMap<K, ImmutableSet<V>> { 1152 1153 @Override 1154 public int size() { 1155 return ImmutableMap.this.size(); 1156 } 1157 1158 @Override 1159 ImmutableSet<K> createKeySet() { 1160 return ImmutableMap.this.keySet(); 1161 } 1162 1163 @Override 1164 public boolean containsKey(@Nullable Object key) { 1165 return ImmutableMap.this.containsKey(key); 1166 } 1167 1168 @Override 1169 public @Nullable ImmutableSet<V> get(@Nullable Object key) { 1170 V outerValue = ImmutableMap.this.get(key); 1171 return (outerValue == null) ? null : ImmutableSet.of(outerValue); 1172 } 1173 1174 @Override 1175 boolean isPartialView() { 1176 return ImmutableMap.this.isPartialView(); 1177 } 1178 1179 @Override 1180 public int hashCode() { 1181 // ImmutableSet.of(value).hashCode() == value.hashCode(), so the hashes are the same 1182 return ImmutableMap.this.hashCode(); 1183 } 1184 1185 @Override 1186 boolean isHashCodeFast() { 1187 return ImmutableMap.this.isHashCodeFast(); 1188 } 1189 1190 @Override 1191 UnmodifiableIterator<Entry<K, ImmutableSet<V>>> entryIterator() { 1192 Iterator<Entry<K, V>> backingIterator = ImmutableMap.this.entrySet().iterator(); 1193 return new UnmodifiableIterator<Entry<K, ImmutableSet<V>>>() { 1194 @Override 1195 public boolean hasNext() { 1196 return backingIterator.hasNext(); 1197 } 1198 1199 @Override 1200 public Entry<K, ImmutableSet<V>> next() { 1201 Entry<K, V> backingEntry = backingIterator.next(); 1202 return new AbstractMapEntry<K, ImmutableSet<V>>() { 1203 @Override 1204 public K getKey() { 1205 return backingEntry.getKey(); 1206 } 1207 1208 @Override 1209 public ImmutableSet<V> getValue() { 1210 return ImmutableSet.of(backingEntry.getValue()); 1211 } 1212 }; 1213 } 1214 }; 1215 } 1216 1217 // redeclare to help optimizers with b/310253115 1218 @SuppressWarnings("RedundantOverride") 1219 @Override 1220 @J2ktIncompatible 1221 @GwtIncompatible 1222 Object writeReplace() { 1223 return super.writeReplace(); 1224 } 1225 } 1226 1227 @Override 1228 public boolean equals(@Nullable Object object) { 1229 return equalsImpl(this, object); 1230 } 1231 1232 abstract boolean isPartialView(); 1233 1234 @Override 1235 public int hashCode() { 1236 return hashCodeImpl(entrySet()); 1237 } 1238 1239 boolean isHashCodeFast() { 1240 return false; 1241 } 1242 1243 @Override 1244 public final String toString() { 1245 return toStringImpl(this); 1246 } 1247 1248 /** 1249 * Serialized type for all ImmutableMap instances. It captures the logical contents and they are 1250 * reconstructed using public factory methods. This ensures that the implementation types remain 1251 * as implementation details. 1252 */ 1253 @J2ktIncompatible // serialization 1254 static class SerializedForm<K, V> implements Serializable { 1255 // This object retains references to collections returned by keySet() and value(). This saves 1256 // bytes when the both the map and its keySet or value collection are written to the same 1257 // instance of ObjectOutputStream. 1258 1259 // TODO(b/160980469): remove support for the old serialization format after some time 1260 private static final boolean USE_LEGACY_SERIALIZATION = true; 1261 1262 private final Object keys; 1263 private final Object values; 1264 1265 SerializedForm(ImmutableMap<K, V> map) { 1266 if (USE_LEGACY_SERIALIZATION) { 1267 Object[] keys = new Object[map.size()]; 1268 Object[] values = new Object[map.size()]; 1269 int i = 0; 1270 // "extends Object" works around https://github.com/typetools/checker-framework/issues/3013 1271 for (Entry<? extends Object, ? extends Object> entry : map.entrySet()) { 1272 keys[i] = entry.getKey(); 1273 values[i] = entry.getValue(); 1274 i++; 1275 } 1276 this.keys = keys; 1277 this.values = values; 1278 return; 1279 } 1280 this.keys = map.keySet(); 1281 this.values = map.values(); 1282 } 1283 1284 @SuppressWarnings("unchecked") 1285 final Object readResolve() { 1286 if (!(this.keys instanceof ImmutableSet)) { 1287 return legacyReadResolve(); 1288 } 1289 1290 ImmutableSet<K> keySet = (ImmutableSet<K>) this.keys; 1291 ImmutableCollection<V> values = (ImmutableCollection<V>) this.values; 1292 1293 Builder<K, V> builder = makeBuilder(keySet.size()); 1294 1295 UnmodifiableIterator<K> keyIter = keySet.iterator(); 1296 UnmodifiableIterator<V> valueIter = values.iterator(); 1297 1298 while (keyIter.hasNext()) { 1299 builder.put(keyIter.next(), valueIter.next()); 1300 } 1301 1302 return builder.buildOrThrow(); 1303 } 1304 1305 @SuppressWarnings("unchecked") 1306 final Object legacyReadResolve() { 1307 K[] keys = (K[]) this.keys; 1308 V[] values = (V[]) this.values; 1309 1310 Builder<K, V> builder = makeBuilder(keys.length); 1311 1312 for (int i = 0; i < keys.length; i++) { 1313 builder.put(keys[i], values[i]); 1314 } 1315 return builder.buildOrThrow(); 1316 } 1317 1318 /** 1319 * Returns a builder that builds the unserialized type. Subclasses should override this method. 1320 */ 1321 Builder<K, V> makeBuilder(int size) { 1322 return new Builder<>(size); 1323 } 1324 1325 @GwtIncompatible private static final long serialVersionUID = 0; 1326 } 1327 1328 /** 1329 * Returns a serializable form of this object. Non-public subclasses should not override this 1330 * method. Publicly-accessible subclasses must override this method and should return a subclass 1331 * of SerializedForm whose readResolve() method returns objects of the subclass type. 1332 */ 1333 @J2ktIncompatible // serialization 1334 Object writeReplace() { 1335 return new SerializedForm<>(this); 1336 } 1337 1338 @J2ktIncompatible // java.io.ObjectInputStream 1339 private void readObject(ObjectInputStream stream) throws InvalidObjectException { 1340 throw new InvalidObjectException("Use SerializedForm"); 1341 } 1342 1343 @GwtIncompatible @J2ktIncompatible private static final long serialVersionUID = 0xcafebabe; 1344}