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