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