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