1 /* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import static com.google.common.collect.testing.Helpers.mapEntry; 20 import static com.google.common.testing.SerializableTester.reserialize; 21 import static com.google.common.truth.Truth.assertThat; 22 import static com.google.common.truth.Truth.assertWithMessage; 23 24 import com.google.common.annotations.GwtCompatible; 25 import com.google.common.annotations.GwtIncompatible; 26 import com.google.common.base.Equivalence; 27 import com.google.common.collect.ImmutableMap.Builder; 28 import com.google.common.collect.testing.AnEnum; 29 import com.google.common.collect.testing.CollectionTestSuiteBuilder; 30 import com.google.common.collect.testing.ListTestSuiteBuilder; 31 import com.google.common.collect.testing.MapTestSuiteBuilder; 32 import com.google.common.collect.testing.TestStringMapGenerator; 33 import com.google.common.collect.testing.features.CollectionFeature; 34 import com.google.common.collect.testing.features.CollectionSize; 35 import com.google.common.collect.testing.features.MapFeature; 36 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfEntriesGenerator; 37 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfEnumMapGenerator; 38 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfGenerator; 39 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapEntryListGenerator; 40 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapGenerator; 41 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapKeyListGenerator; 42 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapUnhashableValuesGenerator; 43 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapValueListGenerator; 44 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapValuesAsSingletonSetGenerator; 45 import com.google.common.testing.CollectorTester; 46 import com.google.common.testing.EqualsTester; 47 import com.google.common.testing.NullPointerTester; 48 import java.io.ByteArrayOutputStream; 49 import java.io.ObjectOutputStream; 50 import java.io.Serializable; 51 import java.util.AbstractMap; 52 import java.util.Arrays; 53 import java.util.Collection; 54 import java.util.Collections; 55 import java.util.EnumMap; 56 import java.util.LinkedHashMap; 57 import java.util.List; 58 import java.util.Map; 59 import java.util.Map.Entry; 60 import java.util.Set; 61 import java.util.regex.Matcher; 62 import java.util.regex.Pattern; 63 import java.util.stream.Collector; 64 import java.util.stream.Stream; 65 import junit.framework.Test; 66 import junit.framework.TestCase; 67 import junit.framework.TestSuite; 68 import org.checkerframework.checker.nullness.qual.Nullable; 69 70 /** 71 * Tests for {@link ImmutableMap}. 72 * 73 * @author Kevin Bourrillion 74 * @author Jesse Wilson 75 */ 76 @GwtCompatible(emulated = true) 77 @SuppressWarnings("AlwaysThrows") 78 public class ImmutableMapTest extends TestCase { 79 80 @GwtIncompatible // suite suite()81 public static Test suite() { 82 TestSuite suite = new TestSuite(); 83 suite.addTestSuite(ImmutableMapTest.class); 84 85 suite.addTest( 86 MapTestSuiteBuilder.using(new ImmutableMapGenerator()) 87 .withFeatures( 88 CollectionSize.ANY, 89 CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS, 90 CollectionFeature.KNOWN_ORDER, 91 MapFeature.REJECTS_DUPLICATES_AT_CREATION, 92 CollectionFeature.ALLOWS_NULL_QUERIES) 93 .named("ImmutableMap") 94 .createTestSuite()); 95 96 suite.addTest( 97 MapTestSuiteBuilder.using( 98 new TestStringMapGenerator() { 99 @Override 100 protected Map<String, String> create(Entry<String, String>[] entries) { 101 ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); 102 builder.putAll(Arrays.asList(entries)); 103 return builder.buildJdkBacked(); 104 } 105 }) 106 .withFeatures( 107 CollectionSize.ANY, 108 CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS, 109 CollectionFeature.KNOWN_ORDER, 110 MapFeature.REJECTS_DUPLICATES_AT_CREATION, 111 CollectionFeature.ALLOWS_NULL_QUERIES) 112 .named("ImmutableMap [JDK backed]") 113 .createTestSuite()); 114 115 suite.addTest( 116 MapTestSuiteBuilder.using(new ImmutableMapCopyOfGenerator()) 117 .withFeatures( 118 CollectionSize.ANY, 119 CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS, 120 CollectionFeature.KNOWN_ORDER, 121 CollectionFeature.ALLOWS_NULL_QUERIES) 122 .named("ImmutableMap.copyOf[Map]") 123 .createTestSuite()); 124 125 suite.addTest( 126 MapTestSuiteBuilder.using(new ImmutableMapCopyOfEntriesGenerator()) 127 .withFeatures( 128 CollectionSize.ANY, 129 MapFeature.REJECTS_DUPLICATES_AT_CREATION, 130 CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS, 131 CollectionFeature.KNOWN_ORDER, 132 CollectionFeature.ALLOWS_NULL_QUERIES) 133 .named("ImmutableMap.copyOf[Iterable<Entry>]") 134 .createTestSuite()); 135 136 suite.addTest( 137 MapTestSuiteBuilder.using(new ImmutableMapCopyOfEnumMapGenerator()) 138 .withFeatures( 139 CollectionSize.ANY, 140 CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS, 141 CollectionFeature.KNOWN_ORDER, 142 CollectionFeature.ALLOWS_NULL_QUERIES) 143 .named("ImmutableMap.copyOf[EnumMap]") 144 .createTestSuite()); 145 146 suite.addTest( 147 MapTestSuiteBuilder.using(new ImmutableMapValuesAsSingletonSetGenerator()) 148 .withFeatures( 149 CollectionSize.ANY, 150 MapFeature.REJECTS_DUPLICATES_AT_CREATION, 151 CollectionFeature.KNOWN_ORDER, 152 CollectionFeature.ALLOWS_NULL_QUERIES) 153 .named("ImmutableMap.asMultimap.asMap") 154 .createTestSuite()); 155 156 suite.addTest( 157 CollectionTestSuiteBuilder.using(new ImmutableMapUnhashableValuesGenerator()) 158 .withFeatures( 159 CollectionSize.ANY, 160 CollectionFeature.KNOWN_ORDER, 161 CollectionFeature.ALLOWS_NULL_QUERIES) 162 .named("ImmutableMap.values, unhashable") 163 .createTestSuite()); 164 165 suite.addTest( 166 ListTestSuiteBuilder.using(new ImmutableMapKeyListGenerator()) 167 .named("ImmutableMap.keySet.asList") 168 .withFeatures( 169 CollectionSize.ANY, 170 CollectionFeature.SERIALIZABLE, 171 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 172 CollectionFeature.ALLOWS_NULL_QUERIES) 173 .createTestSuite()); 174 175 suite.addTest( 176 ListTestSuiteBuilder.using(new ImmutableMapEntryListGenerator()) 177 .named("ImmutableMap.entrySet.asList") 178 .withFeatures( 179 CollectionSize.ANY, 180 CollectionFeature.SERIALIZABLE, 181 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 182 CollectionFeature.ALLOWS_NULL_QUERIES) 183 .createTestSuite()); 184 185 suite.addTest( 186 ListTestSuiteBuilder.using(new ImmutableMapValueListGenerator()) 187 .named("ImmutableMap.values.asList") 188 .withFeatures( 189 CollectionSize.ANY, 190 CollectionFeature.SERIALIZABLE, 191 CollectionFeature.ALLOWS_NULL_QUERIES) 192 .createTestSuite()); 193 194 return suite; 195 } 196 197 // Creation tests 198 testEmptyBuilder()199 public void testEmptyBuilder() { 200 ImmutableMap<String, Integer> map = new Builder<String, Integer>().buildOrThrow(); 201 assertEquals(Collections.<String, Integer>emptyMap(), map); 202 } 203 testSingletonBuilder()204 public void testSingletonBuilder() { 205 ImmutableMap<String, Integer> map = new Builder<String, Integer>().put("one", 1).buildOrThrow(); 206 assertMapEquals(map, "one", 1); 207 } 208 testBuilder()209 public void testBuilder() { 210 ImmutableMap<String, Integer> map = 211 new Builder<String, Integer>() 212 .put("one", 1) 213 .put("two", 2) 214 .put("three", 3) 215 .put("four", 4) 216 .put("five", 5) 217 .buildOrThrow(); 218 assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); 219 } 220 221 @GwtIncompatible testBuilderExactlySizedReusesArray()222 public void testBuilderExactlySizedReusesArray() { 223 ImmutableMap.Builder<Integer, Integer> builder = ImmutableMap.builderWithExpectedSize(10); 224 Entry<Integer, Integer>[] builderArray = builder.entries; 225 for (int i = 0; i < 10; i++) { 226 builder.put(i, i); 227 } 228 Entry<Integer, Integer>[] builderArrayAfterPuts = builder.entries; 229 RegularImmutableMap<Integer, Integer> map = 230 (RegularImmutableMap<Integer, Integer>) builder.buildOrThrow(); 231 Entry<Integer, Integer>[] mapInternalArray = map.entries; 232 assertSame(builderArray, builderArrayAfterPuts); 233 assertSame(builderArray, mapInternalArray); 234 } 235 testBuilder_orderEntriesByValue()236 public void testBuilder_orderEntriesByValue() { 237 ImmutableMap<String, Integer> map = 238 new Builder<String, Integer>() 239 .orderEntriesByValue(Ordering.natural()) 240 .put("three", 3) 241 .put("one", 1) 242 .put("five", 5) 243 .put("four", 4) 244 .put("two", 2) 245 .buildOrThrow(); 246 assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); 247 } 248 testBuilder_orderEntriesByValueAfterExactSizeBuild()249 public void testBuilder_orderEntriesByValueAfterExactSizeBuild() { 250 Builder<String, Integer> builder = new Builder<String, Integer>(2).put("four", 4).put("one", 1); 251 ImmutableMap<String, Integer> keyOrdered = builder.buildOrThrow(); 252 ImmutableMap<String, Integer> valueOrdered = 253 builder.orderEntriesByValue(Ordering.natural()).buildOrThrow(); 254 assertMapEquals(keyOrdered, "four", 4, "one", 1); 255 assertMapEquals(valueOrdered, "one", 1, "four", 4); 256 } 257 testBuilder_orderEntriesByValue_usedTwiceFails()258 public void testBuilder_orderEntriesByValue_usedTwiceFails() { 259 ImmutableMap.Builder<String, Integer> builder = 260 new Builder<String, Integer>().orderEntriesByValue(Ordering.natural()); 261 try { 262 builder.orderEntriesByValue(Ordering.natural()); 263 fail("Expected IllegalStateException"); 264 } catch (IllegalStateException expected) { 265 } 266 } 267 268 @GwtIncompatible // we haven't implemented this testBuilder_orderEntriesByValue_keepingLast()269 public void testBuilder_orderEntriesByValue_keepingLast() { 270 ImmutableMap.Builder<String, Integer> builder = 271 new Builder<String, Integer>() 272 .orderEntriesByValue(Ordering.natural()) 273 .put("three", 3) 274 .put("one", 1) 275 .put("five", 5) 276 .put("four", 3) 277 .put("four", 5) 278 .put("four", 4) // this should win because it's last 279 .put("two", 2); 280 assertMapEquals( 281 builder.buildKeepingLast(), "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); 282 try { 283 builder.buildOrThrow(); 284 fail("Expected exception from duplicate keys"); 285 } catch (IllegalArgumentException expected) { 286 } 287 } 288 289 @GwtIncompatible // we haven't implemented this testBuilder_orderEntriesByValue_keepingLast_builderSizeFieldPreserved()290 public void testBuilder_orderEntriesByValue_keepingLast_builderSizeFieldPreserved() { 291 ImmutableMap.Builder<String, Integer> builder = 292 new Builder<String, Integer>() 293 .orderEntriesByValue(Ordering.natural()) 294 .put("one", 1) 295 .put("one", 1); 296 assertMapEquals(builder.buildKeepingLast(), "one", 1); 297 try { 298 builder.buildOrThrow(); 299 fail("Expected exception from duplicate keys"); 300 } catch (IllegalArgumentException expected) { 301 } 302 } 303 testBuilder_withImmutableEntry()304 public void testBuilder_withImmutableEntry() { 305 ImmutableMap<String, Integer> map = 306 new Builder<String, Integer>().put(Maps.immutableEntry("one", 1)).buildOrThrow(); 307 assertMapEquals(map, "one", 1); 308 } 309 testBuilder_withImmutableEntryAndNullContents()310 public void testBuilder_withImmutableEntryAndNullContents() { 311 Builder<String, Integer> builder = new Builder<>(); 312 try { 313 builder.put(Maps.immutableEntry("one", (Integer) null)); 314 fail(); 315 } catch (NullPointerException expected) { 316 } 317 try { 318 builder.put(Maps.immutableEntry((String) null, 1)); 319 fail(); 320 } catch (NullPointerException expected) { 321 } 322 } 323 324 private static class StringHolder { 325 String string; 326 } 327 testBuilder_withMutableEntry()328 public void testBuilder_withMutableEntry() { 329 ImmutableMap.Builder<String, Integer> builder = new Builder<>(); 330 final StringHolder holder = new StringHolder(); 331 holder.string = "one"; 332 Entry<String, Integer> entry = 333 new AbstractMapEntry<String, Integer>() { 334 @Override 335 public String getKey() { 336 return holder.string; 337 } 338 339 @Override 340 public Integer getValue() { 341 return 1; 342 } 343 }; 344 345 builder.put(entry); 346 holder.string = "two"; 347 assertMapEquals(builder.buildOrThrow(), "one", 1); 348 } 349 testBuilderPutAllWithEmptyMap()350 public void testBuilderPutAllWithEmptyMap() { 351 ImmutableMap<String, Integer> map = 352 new Builder<String, Integer>() 353 .putAll(Collections.<String, Integer>emptyMap()) 354 .buildOrThrow(); 355 assertEquals(Collections.<String, Integer>emptyMap(), map); 356 } 357 testBuilderPutAll()358 public void testBuilderPutAll() { 359 Map<String, Integer> toPut = new LinkedHashMap<>(); 360 toPut.put("one", 1); 361 toPut.put("two", 2); 362 toPut.put("three", 3); 363 Map<String, Integer> moreToPut = new LinkedHashMap<>(); 364 moreToPut.put("four", 4); 365 moreToPut.put("five", 5); 366 367 ImmutableMap<String, Integer> map = 368 new Builder<String, Integer>().putAll(toPut).putAll(moreToPut).buildOrThrow(); 369 assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); 370 } 371 testBuilderReuse()372 public void testBuilderReuse() { 373 Builder<String, Integer> builder = new Builder<>(); 374 ImmutableMap<String, Integer> mapOne = builder.put("one", 1).put("two", 2).buildOrThrow(); 375 ImmutableMap<String, Integer> mapTwo = builder.put("three", 3).put("four", 4).buildOrThrow(); 376 377 assertMapEquals(mapOne, "one", 1, "two", 2); 378 assertMapEquals(mapTwo, "one", 1, "two", 2, "three", 3, "four", 4); 379 } 380 testBuilderPutNullKeyFailsAtomically()381 public void testBuilderPutNullKeyFailsAtomically() { 382 Builder<String, Integer> builder = new Builder<>(); 383 try { 384 builder.put(null, 1); 385 fail(); 386 } catch (NullPointerException expected) { 387 } 388 builder.put("foo", 2); 389 assertMapEquals(builder.buildOrThrow(), "foo", 2); 390 } 391 testBuilderPutImmutableEntryWithNullKeyFailsAtomically()392 public void testBuilderPutImmutableEntryWithNullKeyFailsAtomically() { 393 Builder<String, Integer> builder = new Builder<>(); 394 try { 395 builder.put(Maps.immutableEntry((String) null, 1)); 396 fail(); 397 } catch (NullPointerException expected) { 398 } 399 builder.put("foo", 2); 400 assertMapEquals(builder.buildOrThrow(), "foo", 2); 401 } 402 403 // for GWT compatibility 404 static class SimpleEntry<K, V> extends AbstractMapEntry<K, V> { 405 public K key; 406 public V value; 407 SimpleEntry(K key, V value)408 SimpleEntry(K key, V value) { 409 this.key = key; 410 this.value = value; 411 } 412 413 @Override getKey()414 public K getKey() { 415 return key; 416 } 417 418 @Override getValue()419 public V getValue() { 420 return value; 421 } 422 } 423 testBuilderPutMutableEntryWithNullKeyFailsAtomically()424 public void testBuilderPutMutableEntryWithNullKeyFailsAtomically() { 425 Builder<String, Integer> builder = new Builder<>(); 426 try { 427 builder.put(new SimpleEntry<String, Integer>(null, 1)); 428 fail(); 429 } catch (NullPointerException expected) { 430 } 431 builder.put("foo", 2); 432 assertMapEquals(builder.buildOrThrow(), "foo", 2); 433 } 434 testBuilderPutNullKey()435 public void testBuilderPutNullKey() { 436 Builder<String, Integer> builder = new Builder<>(); 437 try { 438 builder.put(null, 1); 439 fail(); 440 } catch (NullPointerException expected) { 441 } 442 } 443 testBuilderPutNullValue()444 public void testBuilderPutNullValue() { 445 Builder<String, Integer> builder = new Builder<>(); 446 try { 447 builder.put("one", null); 448 fail(); 449 } catch (NullPointerException expected) { 450 } 451 } 452 testBuilderPutNullKeyViaPutAll()453 public void testBuilderPutNullKeyViaPutAll() { 454 Builder<String, Integer> builder = new Builder<>(); 455 try { 456 builder.putAll(Collections.<String, Integer>singletonMap(null, 1)); 457 fail(); 458 } catch (NullPointerException expected) { 459 } 460 } 461 testBuilderPutNullValueViaPutAll()462 public void testBuilderPutNullValueViaPutAll() { 463 Builder<String, Integer> builder = new Builder<>(); 464 try { 465 builder.putAll(Collections.<String, Integer>singletonMap("one", null)); 466 fail(); 467 } catch (NullPointerException expected) { 468 } 469 } 470 testPuttingTheSameKeyTwiceThrowsOnBuild()471 public void testPuttingTheSameKeyTwiceThrowsOnBuild() { 472 Builder<String, Integer> builder = 473 new Builder<String, Integer>() 474 .put("one", 1) 475 .put("one", 1); // throwing on this line might be better but it's too late to change 476 477 try { 478 builder.buildOrThrow(); 479 fail(); 480 } catch (IllegalArgumentException expected) { 481 } 482 } 483 testBuildKeepingLast_allowsOverwrite()484 public void testBuildKeepingLast_allowsOverwrite() { 485 Builder<Integer, String> builder = 486 new Builder<Integer, String>() 487 .put(1, "un") 488 .put(2, "deux") 489 .put(70, "soixante-dix") 490 .put(70, "septante") 491 .put(70, "seventy") 492 .put(1, "one") 493 .put(2, "two"); 494 ImmutableMap<Integer, String> map = builder.buildKeepingLast(); 495 assertMapEquals(map, 1, "one", 2, "two", 70, "seventy"); 496 } 497 testBuildKeepingLast_smallTableSameHash()498 public void testBuildKeepingLast_smallTableSameHash() { 499 String key1 = "QED"; 500 String key2 = "R&D"; 501 assertThat(key1.hashCode()).isEqualTo(key2.hashCode()); 502 ImmutableMap<String, Integer> map = 503 ImmutableMap.<String, Integer>builder() 504 .put(key1, 1) 505 .put(key2, 2) 506 .put(key1, 3) 507 .put(key2, 4) 508 .buildKeepingLast(); 509 assertMapEquals(map, key1, 3, key2, 4); 510 } 511 512 // The java7 branch has different code depending on whether the entry indexes fit in a byte, 513 // short, or int. The small table in testBuildKeepingLast_allowsOverwrite will test the byte 514 // case. This method tests the short case. testBuildKeepingLast_shortTable()515 public void testBuildKeepingLast_shortTable() { 516 Builder<Integer, String> builder = ImmutableMap.builder(); 517 Map<Integer, String> expected = new LinkedHashMap<>(); 518 for (int i = 0; i < 1000; i++) { 519 // Truncate to even key, so we have put(0, "0") then put(0, "1"). Half the entries are 520 // duplicates. 521 Integer key = i & ~1; 522 String value = String.valueOf(i); 523 builder.put(key, value); 524 expected.put(key, value); 525 } 526 ImmutableMap<Integer, String> map = builder.buildKeepingLast(); 527 assertThat(map).hasSize(500); 528 assertThat(map).containsExactlyEntriesIn(expected).inOrder(); 529 } 530 531 // This method tests the int case. testBuildKeepingLast_bigTable()532 public void testBuildKeepingLast_bigTable() { 533 Builder<Integer, String> builder = ImmutableMap.builder(); 534 Map<Integer, String> expected = new LinkedHashMap<>(); 535 for (int i = 0; i < 200_000; i++) { 536 // Truncate to even key, so we have put(0, "0") then put(0, "1"). Half the entries are 537 // duplicates. 538 Integer key = i & ~1; 539 String value = String.valueOf(i); 540 builder.put(key, value); 541 expected.put(key, value); 542 } 543 ImmutableMap<Integer, String> map = builder.buildKeepingLast(); 544 assertThat(map).hasSize(100_000); 545 assertThat(map).containsExactlyEntriesIn(expected).inOrder(); 546 } 547 548 private static class ClassWithTerribleHashCode implements Comparable<ClassWithTerribleHashCode> { 549 private final int value; 550 ClassWithTerribleHashCode(int value)551 ClassWithTerribleHashCode(int value) { 552 this.value = value; 553 } 554 555 @Override compareTo(ClassWithTerribleHashCode that)556 public int compareTo(ClassWithTerribleHashCode that) { 557 return Integer.compare(this.value, that.value); 558 } 559 560 @Override equals(@ullable Object x)561 public boolean equals(@Nullable Object x) { 562 return x instanceof ClassWithTerribleHashCode 563 && ((ClassWithTerribleHashCode) x).value == value; 564 } 565 566 @Override hashCode()567 public int hashCode() { 568 return 23; 569 } 570 571 @Override toString()572 public String toString() { 573 return "ClassWithTerribleHashCode(" + value + ")"; 574 } 575 } 576 577 @GwtIncompatible testBuildKeepingLast_collisions()578 public void testBuildKeepingLast_collisions() { 579 Map<ClassWithTerribleHashCode, Integer> expected = new LinkedHashMap<>(); 580 Builder<ClassWithTerribleHashCode, Integer> builder = new Builder<>(); 581 int size = RegularImmutableMap.MAX_HASH_BUCKET_LENGTH + 10; 582 for (int i = 0; i < size; i++) { 583 ClassWithTerribleHashCode key = new ClassWithTerribleHashCode(i); 584 builder.put(key, i); 585 builder.put(key, -i); 586 expected.put(key, -i); 587 } 588 ImmutableMap<ClassWithTerribleHashCode, Integer> map = builder.buildKeepingLast(); 589 assertThat(map).containsExactlyEntriesIn(expected).inOrder(); 590 assertThat(map).isInstanceOf(JdkBackedImmutableMap.class); 591 } 592 593 @GwtIncompatible // Pattern, Matcher testBuilder_keepingLast_thenOrThrow()594 public void testBuilder_keepingLast_thenOrThrow() { 595 ImmutableMap.Builder<String, Integer> builder = 596 new Builder<String, Integer>() 597 .put("three", 3) 598 .put("one", 1) 599 .put("five", 5) 600 .put("four", 3) 601 .put("four", 5) 602 .put("four", 4) // this should win because it's last 603 .put("two", 2); 604 assertMapEquals( 605 builder.buildKeepingLast(), "three", 3, "one", 1, "five", 5, "four", 4, "two", 2); 606 try { 607 builder.buildOrThrow(); 608 fail("Expected exception from duplicate keys"); 609 } catch (IllegalArgumentException expected) { 610 // We don't really care which values the exception message contains, but they should be 611 // different from each other. If buildKeepingLast() collapsed duplicates, that might end up 612 // not being true. 613 Pattern pattern = Pattern.compile("Multiple entries with same key: four=(.*) and four=(.*)"); 614 assertThat(expected).hasMessageThat().matches(pattern); 615 Matcher matcher = pattern.matcher(expected.getMessage()); 616 assertThat(matcher.matches()).isTrue(); 617 assertThat(matcher.group(1)).isNotEqualTo(matcher.group(2)); 618 } 619 } 620 testOf()621 public void testOf() { 622 assertMapEquals(ImmutableMap.of("one", 1), "one", 1); 623 assertMapEquals(ImmutableMap.of("one", 1, "two", 2), "one", 1, "two", 2); 624 assertMapEquals( 625 ImmutableMap.of("one", 1, "two", 2, "three", 3), "one", 1, "two", 2, "three", 3); 626 assertMapEquals( 627 ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4), 628 "one", 629 1, 630 "two", 631 2, 632 "three", 633 3, 634 "four", 635 4); 636 assertMapEquals( 637 ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4, "five", 5), 638 "one", 639 1, 640 "two", 641 2, 642 "three", 643 3, 644 "four", 645 4, 646 "five", 647 5); 648 assertMapEquals( 649 ImmutableMap.of( 650 "one", 1, 651 "two", 2, 652 "three", 3, 653 "four", 4, 654 "five", 5, 655 "six", 6), 656 "one", 657 1, 658 "two", 659 2, 660 "three", 661 3, 662 "four", 663 4, 664 "five", 665 5, 666 "six", 667 6); 668 assertMapEquals( 669 ImmutableMap.of( 670 "one", 1, 671 "two", 2, 672 "three", 3, 673 "four", 4, 674 "five", 5, 675 "six", 6, 676 "seven", 7), 677 "one", 678 1, 679 "two", 680 2, 681 "three", 682 3, 683 "four", 684 4, 685 "five", 686 5, 687 "six", 688 6, 689 "seven", 690 7); 691 assertMapEquals( 692 ImmutableMap.of( 693 "one", 1, 694 "two", 2, 695 "three", 3, 696 "four", 4, 697 "five", 5, 698 "six", 6, 699 "seven", 7, 700 "eight", 8), 701 "one", 702 1, 703 "two", 704 2, 705 "three", 706 3, 707 "four", 708 4, 709 "five", 710 5, 711 "six", 712 6, 713 "seven", 714 7, 715 "eight", 716 8); 717 assertMapEquals( 718 ImmutableMap.of( 719 "one", 1, 720 "two", 2, 721 "three", 3, 722 "four", 4, 723 "five", 5, 724 "six", 6, 725 "seven", 7, 726 "eight", 8, 727 "nine", 9), 728 "one", 729 1, 730 "two", 731 2, 732 "three", 733 3, 734 "four", 735 4, 736 "five", 737 5, 738 "six", 739 6, 740 "seven", 741 7, 742 "eight", 743 8, 744 "nine", 745 9); 746 assertMapEquals( 747 ImmutableMap.of( 748 "one", 1, 749 "two", 2, 750 "three", 3, 751 "four", 4, 752 "five", 5, 753 "six", 6, 754 "seven", 7, 755 "eight", 8, 756 "nine", 9, 757 "ten", 10), 758 "one", 759 1, 760 "two", 761 2, 762 "three", 763 3, 764 "four", 765 4, 766 "five", 767 5, 768 "six", 769 6, 770 "seven", 771 7, 772 "eight", 773 8, 774 "nine", 775 9, 776 "ten", 777 10); 778 } 779 testOfNullKey()780 public void testOfNullKey() { 781 try { 782 ImmutableMap.of(null, 1); 783 fail(); 784 } catch (NullPointerException expected) { 785 } 786 787 try { 788 ImmutableMap.of("one", 1, null, 2); 789 fail(); 790 } catch (NullPointerException expected) { 791 } 792 } 793 testOfNullValue()794 public void testOfNullValue() { 795 try { 796 ImmutableMap.of("one", null); 797 fail(); 798 } catch (NullPointerException expected) { 799 } 800 801 try { 802 ImmutableMap.of("one", 1, "two", null); 803 fail(); 804 } catch (NullPointerException expected) { 805 } 806 } 807 testOfWithDuplicateKey()808 public void testOfWithDuplicateKey() { 809 try { 810 ImmutableMap.of("one", 1, "one", 1); 811 fail(); 812 } catch (IllegalArgumentException expected) { 813 } 814 } 815 testCopyOfEmptyMap()816 public void testCopyOfEmptyMap() { 817 ImmutableMap<String, Integer> copy = 818 ImmutableMap.copyOf(Collections.<String, Integer>emptyMap()); 819 assertEquals(Collections.<String, Integer>emptyMap(), copy); 820 assertSame(copy, ImmutableMap.copyOf(copy)); 821 } 822 testCopyOfSingletonMap()823 public void testCopyOfSingletonMap() { 824 ImmutableMap<String, Integer> copy = ImmutableMap.copyOf(Collections.singletonMap("one", 1)); 825 assertMapEquals(copy, "one", 1); 826 assertSame(copy, ImmutableMap.copyOf(copy)); 827 } 828 testCopyOf()829 public void testCopyOf() { 830 Map<String, Integer> original = new LinkedHashMap<>(); 831 original.put("one", 1); 832 original.put("two", 2); 833 original.put("three", 3); 834 835 ImmutableMap<String, Integer> copy = ImmutableMap.copyOf(original); 836 assertMapEquals(copy, "one", 1, "two", 2, "three", 3); 837 assertSame(copy, ImmutableMap.copyOf(copy)); 838 } 839 testToImmutableMap()840 public void testToImmutableMap() { 841 Collector<Entry<String, Integer>, ?, ImmutableMap<String, Integer>> collector = 842 ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue); 843 Equivalence<ImmutableMap<String, Integer>> equivalence = 844 Equivalence.equals().<Entry<String, Integer>>pairwise().onResultOf(ImmutableMap::entrySet); 845 CollectorTester.of(collector, equivalence) 846 .expectCollects( 847 ImmutableMap.of("one", 1, "two", 2, "three", 3), 848 mapEntry("one", 1), 849 mapEntry("two", 2), 850 mapEntry("three", 3)); 851 } 852 testToImmutableMap_exceptionOnDuplicateKey()853 public void testToImmutableMap_exceptionOnDuplicateKey() { 854 Collector<Entry<String, Integer>, ?, ImmutableMap<String, Integer>> collector = 855 ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue); 856 try { 857 Stream.of(mapEntry("one", 1), mapEntry("one", 11)).collect(collector); 858 fail("Expected IllegalArgumentException"); 859 } catch (IllegalArgumentException expected) { 860 } 861 } 862 testToImmutableMapMerging()863 public void testToImmutableMapMerging() { 864 Collector<Entry<String, Integer>, ?, ImmutableMap<String, Integer>> collector = 865 ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue, Integer::sum); 866 Equivalence<ImmutableMap<String, Integer>> equivalence = 867 Equivalence.equals().<Entry<String, Integer>>pairwise().onResultOf(ImmutableMap::entrySet); 868 CollectorTester.of(collector, equivalence) 869 .expectCollects( 870 ImmutableMap.of("one", 1, "two", 4, "three", 3), 871 mapEntry("one", 1), 872 mapEntry("two", 2), 873 mapEntry("three", 3), 874 mapEntry("two", 2)); 875 } 876 877 // Non-creation tests 878 testNullGet()879 public void testNullGet() { 880 ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1); 881 assertNull(map.get(null)); 882 } 883 testAsMultimap()884 public void testAsMultimap() { 885 ImmutableMap<String, Integer> map = 886 ImmutableMap.of("one", 1, "won", 1, "two", 2, "too", 2, "three", 3); 887 ImmutableSetMultimap<String, Integer> expected = 888 ImmutableSetMultimap.of("one", 1, "won", 1, "two", 2, "too", 2, "three", 3); 889 assertEquals(expected, map.asMultimap()); 890 } 891 testAsMultimapWhenEmpty()892 public void testAsMultimapWhenEmpty() { 893 ImmutableMap<String, Integer> map = ImmutableMap.of(); 894 ImmutableSetMultimap<String, Integer> expected = ImmutableSetMultimap.of(); 895 assertEquals(expected, map.asMultimap()); 896 } 897 testAsMultimapCaches()898 public void testAsMultimapCaches() { 899 ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1); 900 ImmutableSetMultimap<String, Integer> multimap1 = map.asMultimap(); 901 ImmutableSetMultimap<String, Integer> multimap2 = map.asMultimap(); 902 assertEquals(1, multimap1.asMap().size()); 903 assertSame(multimap1, multimap2); 904 } 905 906 @GwtIncompatible // NullPointerTester 907 @AndroidIncompatible // see ImmutableTableTest.testNullPointerInstance testNullPointers()908 public void testNullPointers() { 909 NullPointerTester tester = new NullPointerTester(); 910 tester.testAllPublicStaticMethods(ImmutableMap.class); 911 tester.testAllPublicInstanceMethods(new ImmutableMap.Builder<Object, Object>()); 912 tester.testAllPublicInstanceMethods(ImmutableMap.of()); 913 tester.testAllPublicInstanceMethods(ImmutableMap.of("one", 1)); 914 tester.testAllPublicInstanceMethods(ImmutableMap.of("one", 1, "two", 2, "three", 3)); 915 } 916 assertMapEquals(Map<K, V> map, Object... alternatingKeysAndValues)917 private static <K, V> void assertMapEquals(Map<K, V> map, Object... alternatingKeysAndValues) { 918 Map<Object, Object> expected = new LinkedHashMap<>(); 919 for (int i = 0; i < alternatingKeysAndValues.length; i += 2) { 920 expected.put(alternatingKeysAndValues[i], alternatingKeysAndValues[i + 1]); 921 } 922 assertThat(map).containsExactlyEntriesIn(expected).inOrder(); 923 } 924 925 private static class IntHolder implements Serializable { 926 public int value; 927 IntHolder(int value)928 public IntHolder(int value) { 929 this.value = value; 930 } 931 932 @Override equals(@ullable Object o)933 public boolean equals(@Nullable Object o) { 934 return (o instanceof IntHolder) && ((IntHolder) o).value == value; 935 } 936 937 @Override hashCode()938 public int hashCode() { 939 return value; 940 } 941 942 private static final long serialVersionUID = 5; 943 } 944 testMutableValues()945 public void testMutableValues() { 946 IntHolder holderA = new IntHolder(1); 947 IntHolder holderB = new IntHolder(2); 948 Map<String, IntHolder> map = ImmutableMap.of("a", holderA, "b", holderB); 949 holderA.value = 3; 950 assertTrue(map.entrySet().contains(Maps.immutableEntry("a", new IntHolder(3)))); 951 Map<String, Integer> intMap = ImmutableMap.of("a", 3, "b", 2); 952 assertEquals(intMap.hashCode(), map.entrySet().hashCode()); 953 assertEquals(intMap.hashCode(), map.hashCode()); 954 } 955 testCopyOfEnumMap()956 public void testCopyOfEnumMap() { 957 EnumMap<AnEnum, String> map = new EnumMap<>(AnEnum.class); 958 map.put(AnEnum.B, "foo"); 959 map.put(AnEnum.C, "bar"); 960 assertTrue(ImmutableMap.copyOf(map) instanceof ImmutableEnumMap); 961 } 962 963 @GwtIncompatible // SerializableTester testViewSerialization()964 public void testViewSerialization() { 965 Map<String, Integer> map = ImmutableMap.of("one", 1, "two", 2, "three", 3); 966 LenientSerializableTester.reserializeAndAssertLenient(map.entrySet()); 967 LenientSerializableTester.reserializeAndAssertLenient(map.keySet()); 968 969 Collection<Integer> reserializedValues = reserialize(map.values()); 970 assertEquals(Lists.newArrayList(map.values()), Lists.newArrayList(reserializedValues)); 971 assertTrue(reserializedValues instanceof ImmutableCollection); 972 } 973 974 @GwtIncompatible // SerializableTester testKeySetIsSerializable_regularImmutableMap()975 public void testKeySetIsSerializable_regularImmutableMap() { 976 class NonSerializableClass {} 977 978 Map<String, NonSerializableClass> map = 979 RegularImmutableMap.fromEntries(ImmutableMap.entryOf("one", new NonSerializableClass())); 980 Set<String> set = map.keySet(); 981 982 LenientSerializableTester.reserializeAndAssertLenient(set); 983 } 984 985 @GwtIncompatible // SerializableTester testKeySetIsSerializable_jdkBackedImmutableMap()986 public void testKeySetIsSerializable_jdkBackedImmutableMap() { 987 class NonSerializableClass {} 988 989 Entry<String, NonSerializableClass>[] entries = 990 arrayOf(ImmutableMap.entryOf("one", new NonSerializableClass())); 991 992 ImmutableMap<String, NonSerializableClass> map = 993 JdkBackedImmutableMap.create(1, entries, /* throwIfDuplicateKeys= */ true); 994 Set<String> set = map.keySet(); 995 996 LenientSerializableTester.reserializeAndAssertLenient(set); 997 } 998 999 @GwtIncompatible // SerializableTester testValuesCollectionIsSerializable_regularImmutableMap()1000 public void testValuesCollectionIsSerializable_regularImmutableMap() { 1001 class NonSerializableClass {} 1002 1003 Map<NonSerializableClass, String> map = 1004 RegularImmutableMap.fromEntries(ImmutableMap.entryOf(new NonSerializableClass(), "value")); 1005 Collection<String> collection = map.values(); 1006 1007 LenientSerializableTester.reserializeAndAssertElementsEqual(collection); 1008 } 1009 1010 @GwtIncompatible // SerializableTester testValuesCollectionIsSerializable_jdkBackedImmutableMap()1011 public void testValuesCollectionIsSerializable_jdkBackedImmutableMap() { 1012 class NonSerializableClass {} 1013 1014 Entry<NonSerializableClass, String>[] entries = 1015 arrayOf(ImmutableMap.entryOf(new NonSerializableClass(), "value")); 1016 1017 ImmutableMap<NonSerializableClass, String> map = 1018 JdkBackedImmutableMap.create(1, entries, /* throwIfDuplicateKeys= */ true); 1019 Collection<String> collection = map.values(); 1020 1021 LenientSerializableTester.reserializeAndAssertElementsEqual(collection); 1022 } 1023 1024 // TODO: Re-enable this test after moving to new serialization format in ImmutableMap. 1025 @GwtIncompatible // SerializableTester 1026 @SuppressWarnings("unchecked") ignore_testSerializationNoDuplication_regularImmutableMap()1027 public void ignore_testSerializationNoDuplication_regularImmutableMap() throws Exception { 1028 // Tests that serializing a map, its keySet, and values only writes the underlying data once. 1029 1030 Entry<Integer, Integer>[] entries = (Entry<Integer, Integer>[]) new Entry<?, ?>[1000]; 1031 for (int i = 0; i < 1000; i++) { 1032 entries[i] = ImmutableMap.entryOf(i, i); 1033 } 1034 1035 ImmutableMap<Integer, Integer> map = RegularImmutableMap.fromEntries(entries); 1036 Set<Integer> keySet = map.keySet(); 1037 Collection<Integer> values = map.values(); 1038 1039 ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 1040 ObjectOutputStream oos = new ObjectOutputStream(bytes); 1041 oos.writeObject(map); 1042 oos.flush(); 1043 1044 int mapSize = bytes.size(); 1045 oos.writeObject(keySet); 1046 oos.writeObject(values); 1047 oos.close(); 1048 1049 int finalSize = bytes.size(); 1050 1051 assertThat(finalSize - mapSize).isLessThan(100); 1052 } 1053 1054 // TODO: Re-enable this test after moving to new serialization format in ImmutableMap. 1055 @GwtIncompatible // SerializableTester 1056 @SuppressWarnings("unchecked") ignore_testSerializationNoDuplication_jdkBackedImmutableMap()1057 public void ignore_testSerializationNoDuplication_jdkBackedImmutableMap() throws Exception { 1058 // Tests that serializing a map, its keySet, and values only writes 1059 // the underlying data once. 1060 1061 Entry<Integer, Integer>[] entries = (Entry<Integer, Integer>[]) new Entry<?, ?>[1000]; 1062 for (int i = 0; i < 1000; i++) { 1063 entries[i] = ImmutableMap.entryOf(i, i); 1064 } 1065 1066 ImmutableMap<Integer, Integer> map = 1067 JdkBackedImmutableMap.create(entries.length, entries, /* throwIfDuplicateKeys= */ true); 1068 Set<Integer> keySet = map.keySet(); 1069 Collection<Integer> values = map.values(); 1070 1071 ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 1072 ObjectOutputStream oos = new ObjectOutputStream(bytes); 1073 oos.writeObject(map); 1074 oos.flush(); 1075 1076 int mapSize = bytes.size(); 1077 oos.writeObject(keySet); 1078 oos.writeObject(values); 1079 oos.close(); 1080 1081 int finalSize = bytes.size(); 1082 1083 assertThat(finalSize - mapSize).isLessThan(100); 1084 } 1085 arrayOf(T... objs)1086 private static <T> T[] arrayOf(T... objs) { 1087 return objs; 1088 } 1089 1090 @GwtIncompatible("assumptions about splitting") testKeySetSplittable()1091 public void testKeySetSplittable() { 1092 ImmutableMap<Integer, Integer> map = 1093 ImmutableMap.<Integer, Integer>builder() 1094 .put(1, 1) 1095 .put(2, 2) 1096 .put(3, 3) 1097 .put(4, 4) 1098 .put(5, 5) 1099 .put(6, 6) 1100 .buildOrThrow(); 1101 assertNotNull(map.keySet().spliterator().trySplit()); 1102 } 1103 testEquals()1104 public void testEquals() { 1105 new EqualsTester() 1106 .addEqualityGroup( 1107 ImmutableMap.of(), 1108 ImmutableMap.builder().buildOrThrow(), 1109 ImmutableMap.ofEntries(), 1110 map()) 1111 .addEqualityGroup( 1112 ImmutableMap.of(1, 1), 1113 ImmutableMap.builder().put(1, 1).buildOrThrow(), 1114 ImmutableMap.ofEntries(entry(1, 1)), 1115 map(1, 1)) 1116 .addEqualityGroup( 1117 ImmutableMap.of(1, 1, 2, 2), 1118 ImmutableMap.builder().put(1, 1).put(2, 2).buildOrThrow(), 1119 ImmutableMap.ofEntries(entry(1, 1), entry(2, 2)), 1120 map(1, 1, 2, 2)) 1121 .addEqualityGroup( 1122 ImmutableMap.of(1, 1, 2, 2, 3, 3), 1123 ImmutableMap.builder().put(1, 1).put(2, 2).put(3, 3).buildOrThrow(), 1124 ImmutableMap.ofEntries(entry(1, 1), entry(2, 2), entry(3, 3)), 1125 map(1, 1, 2, 2, 3, 3)) 1126 .addEqualityGroup( 1127 ImmutableMap.of(1, 4, 2, 2, 3, 3), 1128 ImmutableMap.builder().put(1, 4).put(2, 2).put(3, 3).buildOrThrow(), 1129 ImmutableMap.ofEntries(entry(1, 4), entry(2, 2), entry(3, 3)), 1130 map(1, 4, 2, 2, 3, 3)) 1131 .addEqualityGroup( 1132 ImmutableMap.of(1, 1, 2, 4, 3, 3), 1133 ImmutableMap.builder().put(1, 1).put(2, 4).put(3, 3).buildOrThrow(), 1134 ImmutableMap.ofEntries(entry(1, 1), entry(2, 4), entry(3, 3)), 1135 map(1, 1, 2, 4, 3, 3)) 1136 .addEqualityGroup( 1137 ImmutableMap.of(1, 1, 2, 2, 3, 4), 1138 ImmutableMap.builder().put(1, 1).put(2, 2).put(3, 4).buildOrThrow(), 1139 ImmutableMap.ofEntries(entry(1, 1), entry(2, 2), entry(3, 4)), 1140 map(1, 1, 2, 2, 3, 4)) 1141 .addEqualityGroup( 1142 ImmutableMap.of(1, 2, 2, 3, 3, 1), 1143 ImmutableMap.builder().put(1, 2).put(2, 3).put(3, 1).buildOrThrow(), 1144 ImmutableMap.ofEntries(entry(1, 2), entry(2, 3), entry(3, 1)), 1145 map(1, 2, 2, 3, 3, 1)) 1146 .addEqualityGroup( 1147 ImmutableMap.of(1, 1, 2, 2, 3, 3, 4, 4), 1148 ImmutableMap.builder().put(1, 1).put(2, 2).put(3, 3).put(4, 4).buildOrThrow(), 1149 ImmutableMap.ofEntries(entry(1, 1), entry(2, 2), entry(3, 3), entry(4, 4)), 1150 map(1, 1, 2, 2, 3, 3, 4, 4)) 1151 .addEqualityGroup( 1152 ImmutableMap.of(1, 1, 2, 2, 3, 3, 4, 4, 5, 5), 1153 ImmutableMap.builder().put(1, 1).put(2, 2).put(3, 3).put(4, 4).put(5, 5).buildOrThrow(), 1154 ImmutableMap.ofEntries(entry(1, 1), entry(2, 2), entry(3, 3), entry(4, 4), entry(5, 5)), 1155 map(1, 1, 2, 2, 3, 3, 4, 4, 5, 5)) 1156 .testEquals(); 1157 } 1158 testOfEntriesNull()1159 public void testOfEntriesNull() { 1160 Entry<Integer, Integer> nullKey = entry(null, 23); 1161 try { 1162 ImmutableMap.ofEntries(nullKey); 1163 fail(); 1164 } catch (NullPointerException expected) { 1165 } 1166 Entry<Integer, Integer> nullValue = entry(23, null); 1167 try { 1168 ImmutableMap.ofEntries(nullValue); 1169 fail(); 1170 } catch (NullPointerException expected) { 1171 } 1172 } 1173 map(T... keysAndValues)1174 private static <T> Map<T, T> map(T... keysAndValues) { 1175 assertThat(keysAndValues.length % 2).isEqualTo(0); 1176 LinkedHashMap<T, T> map = new LinkedHashMap<>(); 1177 for (int i = 0; i < keysAndValues.length; i += 2) { 1178 T key = keysAndValues[i]; 1179 T value = keysAndValues[i + 1]; 1180 T old = map.put(key, value); 1181 assertWithMessage("Key %s set to %s and %s", key, value, old).that(old).isNull(); 1182 } 1183 return map; 1184 } 1185 entry(T key, T value)1186 private static <T> Entry<T, T> entry(T key, T value) { 1187 return new AbstractMap.SimpleImmutableEntry<>(key, value); 1188 } 1189 testCopyOfMutableEntryList()1190 public void testCopyOfMutableEntryList() { 1191 List<Entry<String, String>> entryList = 1192 Arrays.asList( 1193 new AbstractMap.SimpleEntry<>("a", "1"), new AbstractMap.SimpleEntry<>("b", "2")); 1194 ImmutableMap<String, String> map = ImmutableMap.copyOf(entryList); 1195 assertThat(map).containsExactly("a", "1", "b", "2").inOrder(); 1196 entryList.get(0).setValue("3"); 1197 assertThat(map).containsExactly("a", "1", "b", "2").inOrder(); 1198 } 1199 testBuilderPutAllEntryList()1200 public void testBuilderPutAllEntryList() { 1201 List<Entry<String, String>> entryList = 1202 Arrays.asList( 1203 new AbstractMap.SimpleEntry<>("a", "1"), new AbstractMap.SimpleEntry<>("b", "2")); 1204 ImmutableMap<String, String> map = 1205 ImmutableMap.<String, String>builder().putAll(entryList).buildOrThrow(); 1206 assertThat(map).containsExactly("a", "1", "b", "2").inOrder(); 1207 entryList.get(0).setValue("3"); 1208 assertThat(map).containsExactly("a", "1", "b", "2").inOrder(); 1209 } 1210 testBuilderPutAllEntryListJdkBacked()1211 public void testBuilderPutAllEntryListJdkBacked() { 1212 List<Entry<String, String>> entryList = 1213 Arrays.asList( 1214 new AbstractMap.SimpleEntry<>("a", "1"), new AbstractMap.SimpleEntry<>("b", "2")); 1215 ImmutableMap<String, String> map = 1216 ImmutableMap.<String, String>builder().putAll(entryList).buildJdkBacked(); 1217 assertThat(map).containsExactly("a", "1", "b", "2").inOrder(); 1218 entryList.get(0).setValue("3"); 1219 assertThat(map).containsExactly("a", "1", "b", "2").inOrder(); 1220 } 1221 } 1222