1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.collect.Maps.transformEntries;
20 import static com.google.common.collect.Maps.transformValues;
21 import static com.google.common.collect.Maps.unmodifiableNavigableMap;
22 import static com.google.common.collect.testing.Helpers.mapEntry;
23 import static com.google.common.truth.Truth.assertThat;
24 import static java.util.Arrays.asList;
25
26 import com.google.common.annotations.GwtCompatible;
27 import com.google.common.annotations.GwtIncompatible;
28 import com.google.common.base.Converter;
29 import com.google.common.base.Equivalence;
30 import com.google.common.base.Function;
31 import com.google.common.base.Functions;
32 import com.google.common.base.Predicate;
33 import com.google.common.base.Predicates;
34 import com.google.common.collect.Maps.EntryTransformer;
35 import com.google.common.collect.Maps.ValueDifferenceImpl;
36 import com.google.common.collect.SetsTest.Derived;
37 import com.google.common.testing.EqualsTester;
38 import com.google.common.testing.NullPointerTester;
39 import com.google.common.testing.SerializableTester;
40
41 import junit.framework.TestCase;
42
43 import java.io.IOException;
44 import java.io.StringReader;
45 import java.lang.reflect.Field;
46 import java.util.Arrays;
47 import java.util.Collection;
48 import java.util.Collections;
49 import java.util.Comparator;
50 import java.util.EnumMap;
51 import java.util.Enumeration;
52 import java.util.HashMap;
53 import java.util.IdentityHashMap;
54 import java.util.Iterator;
55 import java.util.LinkedHashMap;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.Map.Entry;
59 import java.util.NavigableMap;
60 import java.util.NavigableSet;
61 import java.util.Properties;
62 import java.util.Set;
63 import java.util.SortedMap;
64 import java.util.SortedSet;
65 import java.util.TreeMap;
66 import java.util.concurrent.ConcurrentMap;
67
68
69
70
71
72
73
74
75 @GwtCompatible(emulated = true)
76 public class MapsTest extends TestCase {
77
78 private static final Comparator<Integer> SOME_COMPARATOR =
79 Collections.reverseOrder();
80
81 public void testHashMap() {
82 HashMap<Integer, Integer> map = Maps.newHashMap();
83 assertEquals(Collections.emptyMap(), map);
84 }
85
86 public void testHashMapWithInitialMap() {
87 Map<String, Integer> original = new TreeMap<String, Integer>();
88 original.put("a", 1);
89 original.put("b", 2);
90 original.put("c", 3);
91 HashMap<String, Integer> map = Maps.newHashMap(original);
92 assertEquals(original, map);
93 }
94
95 public void testHashMapGeneralizesTypes() {
96 Map<String, Integer> original = new TreeMap<String, Integer>();
97 original.put("a", 1);
98 original.put("b", 2);
99 original.put("c", 3);
100 HashMap<Object, Object> map =
101 Maps.newHashMap((Map<? extends Object, ? extends Object>) original);
102 assertEquals(original, map);
103 }
104
105 public void testCapacityForNegativeSizeFails() {
106 try {
107 Maps.capacity(-1);
108 fail("Negative expected size must result in IllegalArgumentException");
109 } catch (IllegalArgumentException ex) {
110 }
111 }
112
113
114
115
116
117
118
119
120
121
122 @GwtIncompatible("reflection")
123 public void testNewHashMapWithExpectedSize_wontGrow() throws Exception {
124
125
126 assertTrue(bucketsOf(Maps.newHashMapWithExpectedSize(0)) <= 1);
127
128 for (int size = 1; size < 200; size++) {
129 HashMap<Integer, Void> map1 = Maps.newHashMapWithExpectedSize(size);
130
131
132
133 map1.put(0, null);
134
135 int initialBuckets = bucketsOf(map1);
136
137 for (int i = 1; i < size; i++) {
138 map1.put(i, null);
139 }
140 assertEquals("table size after adding " + size + " elements",
141 initialBuckets, bucketsOf(map1));
142
143
144
145
146
147 HashMap<Integer, Void> map2 = Maps.newHashMapWithExpectedSize(size);
148 map2.putAll(map1);
149 assertEquals("table size after adding " + size + "elements",
150 initialBuckets, bucketsOf(map2));
151 }
152 }
153
154 @GwtIncompatible("reflection")
155 private static int bucketsOf(HashMap<?, ?> hashMap) throws Exception {
156 Field tableField = HashMap.class.getDeclaredField("table");
157 tableField.setAccessible(true);
158 Object[] table = (Object[]) tableField.get(hashMap);
159 return table.length;
160 }
161
162 public void testCapacityForLargeSizes() {
163 int[] largeExpectedSizes = new int[] {
164 Integer.MAX_VALUE / 2 - 1,
165 Integer.MAX_VALUE / 2,
166 Integer.MAX_VALUE / 2 + 1,
167 Integer.MAX_VALUE - 1,
168 Integer.MAX_VALUE};
169 for (int expectedSize : largeExpectedSizes) {
170 int capacity = Maps.capacity(expectedSize);
171 assertTrue(
172 "capacity (" + capacity + ") must be >= expectedSize (" + expectedSize + ")",
173 capacity >= expectedSize);
174 }
175 }
176
177 public void testLinkedHashMap() {
178 LinkedHashMap<Integer, Integer> map = Maps.newLinkedHashMap();
179 assertEquals(Collections.emptyMap(), map);
180 }
181
182 @SuppressWarnings("serial")
183 public void testLinkedHashMapWithInitialMap() {
184 Map<String, String> map = new LinkedHashMap<String, String>() {{
185 put("Hello", "World");
186 put("first", "second");
187 put("polygene", "lubricants");
188 put("alpha", "betical");
189 }};
190
191 LinkedHashMap<String, String> copy = Maps.newLinkedHashMap(map);
192
193 Iterator<Entry<String, String>> iter = copy.entrySet().iterator();
194 assertTrue(iter.hasNext());
195 Entry<String, String> entry = iter.next();
196 assertEquals("Hello", entry.getKey());
197 assertEquals("World", entry.getValue());
198 assertTrue(iter.hasNext());
199
200 entry = iter.next();
201 assertEquals("first", entry.getKey());
202 assertEquals("second", entry.getValue());
203 assertTrue(iter.hasNext());
204
205 entry = iter.next();
206 assertEquals("polygene", entry.getKey());
207 assertEquals("lubricants", entry.getValue());
208 assertTrue(iter.hasNext());
209
210 entry = iter.next();
211 assertEquals("alpha", entry.getKey());
212 assertEquals("betical", entry.getValue());
213 assertFalse(iter.hasNext());
214 }
215
216 public void testLinkedHashMapGeneralizesTypes() {
217 Map<String, Integer> original = new LinkedHashMap<String, Integer>();
218 original.put("a", 1);
219 original.put("b", 2);
220 original.put("c", 3);
221 HashMap<Object, Object> map
222 = Maps.<Object, Object>newLinkedHashMap(original);
223 assertEquals(original, map);
224 }
225
226 public void testIdentityHashMap() {
227 IdentityHashMap<Integer, Integer> map = Maps.newIdentityHashMap();
228 assertEquals(Collections.emptyMap(), map);
229 }
230
231 public void testConcurrentMap() {
232 ConcurrentMap<Integer, Integer> map = Maps.newConcurrentMap();
233 assertEquals(Collections.emptyMap(), map);
234 }
235
236 public void testTreeMap() {
237 TreeMap<Integer, Integer> map = Maps.newTreeMap();
238 assertEquals(Collections.emptyMap(), map);
239 assertNull(map.comparator());
240 }
241
242 public void testTreeMapDerived() {
243 TreeMap<Derived, Integer> map = Maps.newTreeMap();
244 assertEquals(Collections.emptyMap(), map);
245 map.put(new Derived("foo"), 1);
246 map.put(new Derived("bar"), 2);
247 assertThat(map.keySet()).has().exactly(
248 new Derived("bar"), new Derived("foo")).inOrder();
249 assertThat(map.values()).has().exactly(2, 1).inOrder();
250 assertNull(map.comparator());
251 }
252
253 public void testTreeMapNonGeneric() {
254 TreeMap<LegacyComparable, Integer> map = Maps.newTreeMap();
255 assertEquals(Collections.emptyMap(), map);
256 map.put(new LegacyComparable("foo"), 1);
257 map.put(new LegacyComparable("bar"), 2);
258 assertThat(map.keySet()).has().exactly(
259 new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
260 assertThat(map.values()).has().exactly(2, 1).inOrder();
261 assertNull(map.comparator());
262 }
263
264 public void testTreeMapWithComparator() {
265 TreeMap<Integer, Integer> map = Maps.newTreeMap(SOME_COMPARATOR);
266 assertEquals(Collections.emptyMap(), map);
267 assertSame(SOME_COMPARATOR, map.comparator());
268 }
269
270 public void testTreeMapWithInitialMap() {
271 SortedMap<Integer, Integer> map = Maps.newTreeMap();
272 map.put(5, 10);
273 map.put(3, 20);
274 map.put(1, 30);
275 TreeMap<Integer, Integer> copy = Maps.newTreeMap(map);
276 assertEquals(copy, map);
277 assertSame(copy.comparator(), map.comparator());
278 }
279
280 public enum SomeEnum { SOME_INSTANCE }
281
282 public void testEnumMap() {
283 EnumMap<SomeEnum, Integer> map = Maps.newEnumMap(SomeEnum.class);
284 assertEquals(Collections.emptyMap(), map);
285 map.put(SomeEnum.SOME_INSTANCE, 0);
286 assertEquals(Collections.singletonMap(SomeEnum.SOME_INSTANCE, 0), map);
287 }
288
289 public void testEnumMapNullClass() {
290 try {
291 Maps.<SomeEnum, Long>newEnumMap((Class<MapsTest.SomeEnum>) null);
292 fail("no exception thrown");
293 } catch (NullPointerException expected) {
294 }
295 }
296
297 public void testEnumMapWithInitialEnumMap() {
298 EnumMap<SomeEnum, Integer> original = Maps.newEnumMap(SomeEnum.class);
299 original.put(SomeEnum.SOME_INSTANCE, 0);
300 EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
301 assertEquals(original, copy);
302 }
303
304 public void testEnumMapWithInitialEmptyEnumMap() {
305 EnumMap<SomeEnum, Integer> original = Maps.newEnumMap(SomeEnum.class);
306 EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
307 assertEquals(original, copy);
308 assertNotSame(original, copy);
309 }
310
311 public void testEnumMapWithInitialMap() {
312 HashMap<SomeEnum, Integer> original = Maps.newHashMap();
313 original.put(SomeEnum.SOME_INSTANCE, 0);
314 EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
315 assertEquals(original, copy);
316 }
317
318 public void testEnumMapWithInitialEmptyMap() {
319 Map<SomeEnum, Integer> original = Maps.newHashMap();
320 try {
321 Maps.newEnumMap(original);
322 fail("Empty map must result in an IllegalArgumentException");
323 } catch (IllegalArgumentException expected) {}
324 }
325
326 public void testToStringImplWithNullKeys() throws Exception {
327 Map<String, String> hashmap = Maps.newHashMap();
328 hashmap.put("foo", "bar");
329 hashmap.put(null, "baz");
330
331 assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
332 }
333
334 public void testToStringImplWithNullValues() throws Exception {
335 Map<String, String> hashmap = Maps.newHashMap();
336 hashmap.put("foo", "bar");
337 hashmap.put("baz", null);
338
339 assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
340 }
341
342 @GwtIncompatible("NullPointerTester")
343 public void testNullPointerExceptions() {
344 new NullPointerTester().testAllPublicStaticMethods(Maps.class);
345 }
346
347 private static final Map<Integer, Integer> EMPTY
348 = Collections.emptyMap();
349 private static final Map<Integer, Integer> SINGLETON
350 = Collections.singletonMap(1, 2);
351
352 public void testMapDifferenceEmptyEmpty() {
353 MapDifference<Integer, Integer> diff = Maps.difference(EMPTY, EMPTY);
354 assertTrue(diff.areEqual());
355 assertEquals(EMPTY, diff.entriesOnlyOnLeft());
356 assertEquals(EMPTY, diff.entriesOnlyOnRight());
357 assertEquals(EMPTY, diff.entriesInCommon());
358 assertEquals(EMPTY, diff.entriesDiffering());
359 assertEquals("equal", diff.toString());
360 }
361
362 public void testMapDifferenceEmptySingleton() {
363 MapDifference<Integer, Integer> diff = Maps.difference(EMPTY, SINGLETON);
364 assertFalse(diff.areEqual());
365 assertEquals(EMPTY, diff.entriesOnlyOnLeft());
366 assertEquals(SINGLETON, diff.entriesOnlyOnRight());
367 assertEquals(EMPTY, diff.entriesInCommon());
368 assertEquals(EMPTY, diff.entriesDiffering());
369 assertEquals("not equal: only on right={1=2}", diff.toString());
370 }
371
372 public void testMapDifferenceSingletonEmpty() {
373 MapDifference<Integer, Integer> diff = Maps.difference(SINGLETON, EMPTY);
374 assertFalse(diff.areEqual());
375 assertEquals(SINGLETON, diff.entriesOnlyOnLeft());
376 assertEquals(EMPTY, diff.entriesOnlyOnRight());
377 assertEquals(EMPTY, diff.entriesInCommon());
378 assertEquals(EMPTY, diff.entriesDiffering());
379 assertEquals("not equal: only on left={1=2}", diff.toString());
380 }
381
382 public void testMapDifferenceTypical() {
383 Map<Integer, String> left = ImmutableMap.of(
384 1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
385 Map<Integer, String> right = ImmutableMap.of(
386 1, "a", 3, "f", 5, "g", 6, "z");
387
388 MapDifference<Integer, String> diff1 = Maps.difference(left, right);
389 assertFalse(diff1.areEqual());
390 assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft());
391 assertEquals(ImmutableMap.of(6, "z"), diff1.entriesOnlyOnRight());
392 assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon());
393 assertEquals(ImmutableMap.of(3,
394 ValueDifferenceImpl.create("c", "f"), 5,
395 ValueDifferenceImpl.create("e", "g")),
396 diff1.entriesDiffering());
397 assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=z}: "
398 + "value differences={3=(c, f), 5=(e, g)}", diff1.toString());
399
400 MapDifference<Integer, String> diff2 = Maps.difference(right, left);
401 assertFalse(diff2.areEqual());
402 assertEquals(ImmutableMap.of(6, "z"), diff2.entriesOnlyOnLeft());
403 assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight());
404 assertEquals(ImmutableMap.of(1, "a"), diff2.entriesInCommon());
405 assertEquals(ImmutableMap.of(3,
406 ValueDifferenceImpl.create("f", "c"), 5,
407 ValueDifferenceImpl.create("g", "e")),
408 diff2.entriesDiffering());
409 assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: "
410 + "value differences={3=(f, c), 5=(g, e)}", diff2.toString());
411 }
412
413 public void testMapDifferenceEquals() {
414 Map<Integer, String> left = ImmutableMap.of(
415 1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
416 Map<Integer, String> right = ImmutableMap.of(
417 1, "a", 3, "f", 5, "g", 6, "z");
418 Map<Integer, String> right2 = ImmutableMap.of(
419 1, "a", 3, "h", 5, "g", 6, "z");
420 MapDifference<Integer, String> original = Maps.difference(left, right);
421 MapDifference<Integer, String> same = Maps.difference(left, right);
422 MapDifference<Integer, String> reverse = Maps.difference(right, left);
423 MapDifference<Integer, String> diff2 = Maps.difference(left, right2);
424
425 new EqualsTester()
426 .addEqualityGroup(original, same)
427 .addEqualityGroup(reverse)
428 .addEqualityGroup(diff2)
429 .testEquals();
430 }
431
432 public void testMapDifferencePredicateTypical() {
433 Map<Integer, String> left = ImmutableMap.of(
434 1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
435 Map<Integer, String> right = ImmutableMap.of(
436 1, "A", 3, "F", 5, "G", 6, "Z");
437
438
439
440 Equivalence<String> caseInsensitiveEquivalence = Equivalence.equals().onResultOf(
441 new Function<String, String>() {
442 @Override public String apply(String input) {
443 return input.toLowerCase();
444 }
445 });
446
447 MapDifference<Integer, String> diff1 = Maps.difference(left, right,
448 caseInsensitiveEquivalence);
449 assertFalse(diff1.areEqual());
450 assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft());
451 assertEquals(ImmutableMap.of(6, "Z"), diff1.entriesOnlyOnRight());
452 assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon());
453 assertEquals(ImmutableMap.of(3,
454 ValueDifferenceImpl.create("c", "F"), 5,
455 ValueDifferenceImpl.create("e", "G")),
456 diff1.entriesDiffering());
457 assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=Z}: "
458 + "value differences={3=(c, F), 5=(e, G)}", diff1.toString());
459
460 MapDifference<Integer, String> diff2 = Maps.difference(right, left,
461 caseInsensitiveEquivalence);
462 assertFalse(diff2.areEqual());
463 assertEquals(ImmutableMap.of(6, "Z"), diff2.entriesOnlyOnLeft());
464 assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight());
465 assertEquals(ImmutableMap.of(1, "A"), diff2.entriesInCommon());
466 assertEquals(ImmutableMap.of(3,
467 ValueDifferenceImpl.create("F", "c"), 5,
468 ValueDifferenceImpl.create("G", "e")),
469 diff2.entriesDiffering());
470 assertEquals("not equal: only on left={6=Z}: only on right={2=b, 4=d}: "
471 + "value differences={3=(F, c), 5=(G, e)}", diff2.toString());
472 }
473
474 private static final SortedMap<Integer, Integer> SORTED_EMPTY = Maps.newTreeMap();
475 private static final SortedMap<Integer, Integer> SORTED_SINGLETON =
476 ImmutableSortedMap.of(1, 2);
477
478 public void testMapDifferenceOfSortedMapIsSorted() {
479 Map<Integer, Integer> map = SORTED_SINGLETON;
480 MapDifference<Integer, Integer> difference = Maps.difference(map, EMPTY);
481 assertTrue(difference instanceof SortedMapDifference);
482 }
483
484 public void testSortedMapDifferenceEmptyEmpty() {
485 SortedMapDifference<Integer, Integer> diff =
486 Maps.difference(SORTED_EMPTY, SORTED_EMPTY);
487 assertTrue(diff.areEqual());
488 assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft());
489 assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight());
490 assertEquals(SORTED_EMPTY, diff.entriesInCommon());
491 assertEquals(SORTED_EMPTY, diff.entriesDiffering());
492 assertEquals("equal", diff.toString());
493 }
494
495 public void testSortedMapDifferenceEmptySingleton() {
496 SortedMapDifference<Integer, Integer> diff =
497 Maps.difference(SORTED_EMPTY, SORTED_SINGLETON);
498 assertFalse(diff.areEqual());
499 assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft());
500 assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnRight());
501 assertEquals(SORTED_EMPTY, diff.entriesInCommon());
502 assertEquals(SORTED_EMPTY, diff.entriesDiffering());
503 assertEquals("not equal: only on right={1=2}", diff.toString());
504 }
505
506 public void testSortedMapDifferenceSingletonEmpty() {
507 SortedMapDifference<Integer, Integer> diff =
508 Maps.difference(SORTED_SINGLETON, SORTED_EMPTY);
509 assertFalse(diff.areEqual());
510 assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnLeft());
511 assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight());
512 assertEquals(SORTED_EMPTY, diff.entriesInCommon());
513 assertEquals(SORTED_EMPTY, diff.entriesDiffering());
514 assertEquals("not equal: only on left={1=2}", diff.toString());
515 }
516
517 public void testSortedMapDifferenceTypical() {
518 SortedMap<Integer, String> left =
519 ImmutableSortedMap.<Integer, String>reverseOrder()
520 .put(1, "a").put(2, "b").put(3, "c").put(4, "d").put(5, "e")
521 .build();
522
523 SortedMap<Integer, String> right =
524 ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z");
525
526 SortedMapDifference<Integer, String> diff1 =
527 Maps.difference(left, right);
528 assertFalse(diff1.areEqual());
529 assertThat(diff1.entriesOnlyOnLeft().entrySet()).has().exactly(
530 Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b")).inOrder();
531 assertThat(diff1.entriesOnlyOnRight().entrySet()).has().item(
532 Maps.immutableEntry(6, "z"));
533 assertThat(diff1.entriesInCommon().entrySet()).has().item(
534 Maps.immutableEntry(1, "a"));
535 assertThat(diff1.entriesDiffering().entrySet()).has().exactly(
536 Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")),
537 Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f"))).inOrder();
538 assertEquals("not equal: only on left={4=d, 2=b}: only on right={6=z}: "
539 + "value differences={5=(e, g), 3=(c, f)}", diff1.toString());
540
541 SortedMapDifference<Integer, String> diff2 =
542 Maps.difference(right, left);
543 assertFalse(diff2.areEqual());
544 assertThat(diff2.entriesOnlyOnLeft().entrySet()).has().item(
545 Maps.immutableEntry(6, "z"));
546 assertThat(diff2.entriesOnlyOnRight().entrySet()).has().exactly(
547 Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
548 assertThat(diff1.entriesInCommon().entrySet()).has().item(
549 Maps.immutableEntry(1, "a"));
550 assertEquals(ImmutableMap.of(
551 3, ValueDifferenceImpl.create("f", "c"),
552 5, ValueDifferenceImpl.create("g", "e")),
553 diff2.entriesDiffering());
554 assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: "
555 + "value differences={3=(f, c), 5=(g, e)}", diff2.toString());
556 }
557
558 public void testSortedMapDifferenceImmutable() {
559 SortedMap<Integer, String> left = Maps.newTreeMap(
560 ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e"));
561 SortedMap<Integer, String> right =
562 Maps.newTreeMap(ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z"));
563
564 SortedMapDifference<Integer, String> diff1 =
565 Maps.difference(left, right);
566 left.put(6, "z");
567 assertFalse(diff1.areEqual());
568 assertThat(diff1.entriesOnlyOnLeft().entrySet()).has().exactly(
569 Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
570 assertThat(diff1.entriesOnlyOnRight().entrySet()).has().item(
571 Maps.immutableEntry(6, "z"));
572 assertThat(diff1.entriesInCommon().entrySet()).has().item(
573 Maps.immutableEntry(1, "a"));
574 assertThat(diff1.entriesDiffering().entrySet()).has().exactly(
575 Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")),
576 Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g"))).inOrder();
577 try {
578 diff1.entriesInCommon().put(7, "x");
579 fail();
580 } catch (UnsupportedOperationException expected) {
581 }
582 try {
583 diff1.entriesOnlyOnLeft().put(7, "x");
584 fail();
585 } catch (UnsupportedOperationException expected) {
586 }
587 try {
588 diff1.entriesOnlyOnRight().put(7, "x");
589 fail();
590 } catch (UnsupportedOperationException expected) {
591 }
592 }
593
594 public void testSortedMapDifferenceEquals() {
595 SortedMap<Integer, String> left =
596 ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
597 SortedMap<Integer, String> right =
598 ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z");
599 SortedMap<Integer, String> right2 =
600 ImmutableSortedMap.of(1, "a", 3, "h", 5, "g", 6, "z");
601 SortedMapDifference<Integer, String> original =
602 Maps.difference(left, right);
603 SortedMapDifference<Integer, String> same =
604 Maps.difference(left, right);
605 SortedMapDifference<Integer, String> reverse =
606 Maps.difference(right, left);
607 SortedMapDifference<Integer, String> diff2 =
608 Maps.difference(left, right2);
609
610 new EqualsTester()
611 .addEqualityGroup(original, same)
612 .addEqualityGroup(reverse)
613 .addEqualityGroup(diff2)
614 .testEquals();
615 }
616
617 private static final Function<String, Integer> LENGTH_FUNCTION =
618 new Function<String, Integer>() {
619 @Override
620 public Integer apply(String input) {
621 return input.length();
622 }
623 };
624
625 public void testAsMap() {
626 Set<String> strings = ImmutableSet.of("one", "two", "three");
627 Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
628 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
629 assertEquals(Integer.valueOf(5), map.get("three"));
630 assertNull(map.get("five"));
631 assertThat(map.entrySet()).has().exactly(
632 mapEntry("one", 3),
633 mapEntry("two", 3),
634 mapEntry("three", 5)).inOrder();
635 }
636
637 public void testAsMapReadsThrough() {
638 Set<String> strings = Sets.newLinkedHashSet();
639 Collections.addAll(strings, "one", "two", "three");
640 Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
641 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
642 assertNull(map.get("four"));
643 strings.add("four");
644 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5, "four", 4), map);
645 assertEquals(Integer.valueOf(4), map.get("four"));
646 }
647
648 public void testAsMapWritesThrough() {
649 Set<String> strings = Sets.newLinkedHashSet();
650 Collections.addAll(strings, "one", "two", "three");
651 Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
652 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
653 assertEquals(Integer.valueOf(3), map.remove("two"));
654 assertThat(strings).has().exactly("one", "three").inOrder();
655 }
656
657 public void testAsMapEmpty() {
658 Set<String> strings = ImmutableSet.of();
659 Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
660 assertThat(map.entrySet()).isEmpty();
661 assertTrue(map.isEmpty());
662 assertNull(map.get("five"));
663 }
664
665 private static class NonNavigableSortedSet
666 extends ForwardingSortedSet<String> {
667 private final SortedSet<String> delegate = Sets.newTreeSet();
668
669 @Override
670 protected SortedSet<String> delegate() {
671 return delegate;
672 }
673 }
674
675 public void testAsMapReturnsSortedMapForSortedSetInput() {
676 Set<String> set = new NonNavigableSortedSet();
677 assertTrue(Maps.asMap(set, Functions.identity()) instanceof SortedMap);
678 }
679
680 public void testAsMapSorted() {
681 SortedSet<String> strings = new NonNavigableSortedSet();
682 Collections.addAll(strings, "one", "two", "three");
683 SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
684 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
685 assertEquals(Integer.valueOf(5), map.get("three"));
686 assertNull(map.get("five"));
687 assertThat(map.entrySet()).has().exactly(
688 mapEntry("one", 3),
689 mapEntry("three", 5),
690 mapEntry("two", 3)).inOrder();
691 assertThat(map.tailMap("onea").entrySet()).has().exactly(
692 mapEntry("three", 5),
693 mapEntry("two", 3)).inOrder();
694 assertThat(map.subMap("one", "two").entrySet()).has().exactly(
695 mapEntry("one", 3),
696 mapEntry("three", 5)).inOrder();
697 }
698
699 public void testAsMapSortedReadsThrough() {
700 SortedSet<String> strings = new NonNavigableSortedSet();
701 Collections.addAll(strings, "one", "two", "three");
702 SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
703 assertNull(map.comparator());
704 assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
705 assertNull(map.get("four"));
706 strings.add("four");
707 assertEquals(
708 ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
709 map);
710 assertEquals(Integer.valueOf(4), map.get("four"));
711 SortedMap<String, Integer> headMap = map.headMap("two");
712 assertEquals(
713 ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
714 headMap);
715 strings.add("five");
716 strings.remove("one");
717 assertEquals(
718 ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
719 headMap);
720 assertThat(map.entrySet()).has().exactly(
721 mapEntry("five", 4),
722 mapEntry("four", 4),
723 mapEntry("three", 5),
724 mapEntry("two", 3)).inOrder();
725 }
726
727 public void testAsMapSortedWritesThrough() {
728 SortedSet<String> strings = new NonNavigableSortedSet();
729 Collections.addAll(strings, "one", "two", "three");
730 SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
731 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
732 assertEquals(Integer.valueOf(3), map.remove("two"));
733 assertThat(strings).has().exactly("one", "three").inOrder();
734 }
735
736 public void testAsMapSortedSubViewKeySetsDoNotSupportAdd() {
737 SortedMap<String, Integer> map = Maps.asMap(
738 new NonNavigableSortedSet(), LENGTH_FUNCTION);
739 try {
740 map.subMap("a", "z").keySet().add("a");
741 fail();
742 } catch (UnsupportedOperationException expected) {
743 }
744 try {
745 map.tailMap("a").keySet().add("a");
746 fail();
747 } catch (UnsupportedOperationException expected) {
748 }
749 try {
750 map.headMap("r").keySet().add("a");
751 fail();
752 } catch (UnsupportedOperationException expected) {
753 }
754 try {
755 map.headMap("r").tailMap("m").keySet().add("a");
756 fail();
757 } catch (UnsupportedOperationException expected) {
758 }
759 }
760
761 public void testAsMapSortedEmpty() {
762 SortedSet<String> strings = new NonNavigableSortedSet();
763 SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
764 assertThat(map.entrySet()).isEmpty();
765 assertTrue(map.isEmpty());
766 assertNull(map.get("five"));
767 }
768
769 @GwtIncompatible("NavigableMap")
770 public void testAsMapReturnsNavigableMapForNavigableSetInput() {
771 Set<String> set = Sets.newTreeSet();
772 assertTrue(Maps.asMap(set, Functions.identity()) instanceof NavigableMap);
773 }
774
775 @GwtIncompatible("NavigableMap")
776 public void testAsMapNavigable() {
777 NavigableSet<String> strings =
778 Sets.newTreeSet(asList("one", "two", "three"));
779 NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
780 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
781 assertEquals(Integer.valueOf(5), map.get("three"));
782 assertNull(map.get("five"));
783 assertThat(map.entrySet()).has().exactly(
784 mapEntry("one", 3),
785 mapEntry("three", 5),
786 mapEntry("two", 3)).inOrder();
787 assertThat(map.tailMap("onea").entrySet()).has().exactly(
788 mapEntry("three", 5),
789 mapEntry("two", 3)).inOrder();
790 assertThat(map.subMap("one", "two").entrySet()).has().exactly(
791 mapEntry("one", 3),
792 mapEntry("three", 5)).inOrder();
793
794 assertEquals(ImmutableSortedMap.of("two", 3, "three", 5),
795 map.tailMap("three", true));
796 assertEquals(ImmutableSortedMap.of("one", 3, "three", 5),
797 map.headMap("two", false));
798 assertEquals(ImmutableSortedMap.of("three", 5),
799 map.subMap("one", false, "tr", true));
800
801 assertEquals("three", map.higherKey("one"));
802 assertEquals("three", map.higherKey("r"));
803 assertEquals("three", map.ceilingKey("r"));
804 assertEquals("one", map.ceilingKey("one"));
805 assertEquals(mapEntry("three", 5), map.higherEntry("one"));
806 assertEquals(mapEntry("one", 3), map.ceilingEntry("one"));
807 assertEquals("one", map.lowerKey("three"));
808 assertEquals("one", map.lowerKey("r"));
809 assertEquals("one", map.floorKey("r"));
810 assertEquals("three", map.floorKey("three"));
811
812 assertThat(map.descendingMap().entrySet()).has().exactly(
813 mapEntry("two", 3),
814 mapEntry("three", 5),
815 mapEntry("one", 3)).inOrder();
816 assertEquals(map.headMap("three", true),
817 map.descendingMap().tailMap("three", true));
818 assertThat(map.tailMap("three", false).entrySet()).has().item(
819 mapEntry("two", 3));
820 assertNull(map.tailMap("three", true).lowerEntry("three"));
821 assertThat(map.headMap("two", false).values()).has().exactly(3, 5).inOrder();
822 assertThat(map.headMap("two", false).descendingMap().values())
823 .has().exactly(5, 3).inOrder();
824 assertThat(map.descendingKeySet()).has().exactly(
825 "two", "three", "one").inOrder();
826
827 assertEquals(mapEntry("one", 3), map.pollFirstEntry());
828 assertEquals(mapEntry("two", 3), map.pollLastEntry());
829 assertEquals(1, map.size());
830 }
831
832 @GwtIncompatible("NavigableMap")
833 public void testAsMapNavigableReadsThrough() {
834 NavigableSet<String> strings = Sets.newTreeSet();
835 Collections.addAll(strings, "one", "two", "three");
836 NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
837 assertNull(map.comparator());
838 assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
839 assertNull(map.get("four"));
840 strings.add("four");
841 assertEquals(
842 ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
843 map);
844 assertEquals(Integer.valueOf(4), map.get("four"));
845 SortedMap<String, Integer> headMap = map.headMap("two");
846 assertEquals(
847 ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
848 headMap);
849 strings.add("five");
850 strings.remove("one");
851 assertEquals(
852 ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
853 headMap);
854 assertThat(map.entrySet()).has().exactly(
855 mapEntry("five", 4),
856 mapEntry("four", 4),
857 mapEntry("three", 5),
858 mapEntry("two", 3)).inOrder();
859
860 NavigableMap<String, Integer> tailMap = map.tailMap("s", true);
861 NavigableMap<String, Integer> subMap = map.subMap("a", true, "t", false);
862
863 strings.add("six");
864 strings.remove("two");
865 assertThat(tailMap.entrySet()).has().exactly(
866 mapEntry("six", 3),
867 mapEntry("three", 5)).inOrder();
868 assertThat(subMap.entrySet()).has().exactly(
869 mapEntry("five", 4),
870 mapEntry("four", 4),
871 mapEntry("six", 3)).inOrder();
872 }
873
874 @GwtIncompatible("NavigableMap")
875 public void testAsMapNavigableWritesThrough() {
876 NavigableSet<String> strings = Sets.newTreeSet();
877 Collections.addAll(strings, "one", "two", "three");
878 NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
879 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
880 assertEquals(Integer.valueOf(3), map.remove("two"));
881 assertThat(strings).has().exactly("one", "three").inOrder();
882 assertEquals(mapEntry("three", 5),
883 map.subMap("one", false, "zzz", true).pollLastEntry());
884 assertThat(strings).has().item("one");
885 }
886
887 @GwtIncompatible("NavigableMap")
888 public void testAsMapNavigableSubViewKeySetsDoNotSupportAdd() {
889 NavigableMap<String, Integer> map = Maps.asMap(
890 Sets.<String>newTreeSet(), LENGTH_FUNCTION);
891 try {
892 map.descendingKeySet().add("a");
893 fail();
894 } catch (UnsupportedOperationException expected) {
895 }
896 try {
897 map.subMap("a", true, "z", false).keySet().add("a");
898 fail();
899 } catch (UnsupportedOperationException expected) {
900 }
901 try {
902 map.tailMap("a", true).keySet().add("a");
903 fail();
904 } catch (UnsupportedOperationException expected) {
905 }
906 try {
907 map.headMap("r", true).keySet().add("a");
908 fail();
909 } catch (UnsupportedOperationException expected) {
910 }
911 try {
912 map.headMap("r", false).tailMap("m", true).keySet().add("a");
913 fail();
914 } catch (UnsupportedOperationException expected) {
915 }
916 }
917
918 @GwtIncompatible("NavigableMap")
919 public void testAsMapNavigableEmpty() {
920 NavigableSet<String> strings = ImmutableSortedSet.of();
921 NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
922 assertThat(map.entrySet()).isEmpty();
923 assertTrue(map.isEmpty());
924 assertNull(map.get("five"));
925 }
926
927 public void testToMap() {
928 Iterable<String> strings = ImmutableList.of("one", "two", "three");
929 ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
930 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
931 assertThat(map.entrySet()).has().exactly(
932 mapEntry("one", 3),
933 mapEntry("two", 3),
934 mapEntry("three", 5)).inOrder();
935 }
936
937 public void testToMapIterator() {
938 Iterator<String> strings = ImmutableList.of("one", "two", "three").iterator();
939 ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
940 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
941 assertThat(map.entrySet()).has().exactly(
942 mapEntry("one", 3),
943 mapEntry("two", 3),
944 mapEntry("three", 5)).inOrder();
945 }
946
947 public void testToMapWithDuplicateKeys() {
948 Iterable<String> strings = ImmutableList.of("one", "two", "three", "two", "one");
949 ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
950 assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
951 assertThat(map.entrySet()).has().exactly(
952 mapEntry("one", 3),
953 mapEntry("two", 3),
954 mapEntry("three", 5)).inOrder();
955 }
956
957 public void testToMapWithNullKeys() {
958 Iterable<String> strings = Arrays.asList("one", null, "three");
959 try {
960 Maps.toMap(strings, Functions.constant("foo"));
961 fail();
962 } catch (NullPointerException expected) {
963 }
964 }
965
966 public void testToMapWithNullValues() {
967 Iterable<String> strings = ImmutableList.of("one", "two", "three");
968 try {
969 Maps.toMap(strings, Functions.constant(null));
970 fail();
971 } catch (NullPointerException expected) {
972 }
973 }
974
975 private static final BiMap<Integer, String> INT_TO_STRING_MAP =
976 new ImmutableBiMap.Builder<Integer, String>()
977 .put(1, "one")
978 .put(2, "two")
979 .put(3, "three")
980 .build();
981
982 public void testUniqueIndexCollection() {
983 ImmutableMap<Integer, String> outputMap =
984 Maps.uniqueIndex(INT_TO_STRING_MAP.values(),
985 Functions.forMap(INT_TO_STRING_MAP.inverse()));
986 assertEquals(INT_TO_STRING_MAP, outputMap);
987 }
988
989 public void testUniqueIndexIterable() {
990 ImmutableMap<Integer, String> outputMap =
991 Maps.uniqueIndex(new Iterable<String>() {
992 @Override
993 public Iterator<String> iterator() {
994 return INT_TO_STRING_MAP.values().iterator();
995 }
996 },
997 Functions.forMap(INT_TO_STRING_MAP.inverse()));
998 assertEquals(INT_TO_STRING_MAP, outputMap);
999 }
1000
1001 public void testUniqueIndexIterator() {
1002 ImmutableMap<Integer, String> outputMap =
1003 Maps.uniqueIndex(INT_TO_STRING_MAP.values().iterator(),
1004 Functions.forMap(INT_TO_STRING_MAP.inverse()));
1005 assertEquals(INT_TO_STRING_MAP, outputMap);
1006 }
1007
1008
1009 public void testUniqueIndexDuplicates() {
1010 try {
1011 Maps.uniqueIndex(ImmutableSet.of("one", "uno"), Functions.constant(1));
1012 fail();
1013 } catch (IllegalArgumentException expected) {
1014 }
1015 }
1016
1017
1018 public void testUniqueIndexNullValue() {
1019 List<String> listWithNull = Lists.newArrayList((String) null);
1020 try {
1021 Maps.uniqueIndex(listWithNull, Functions.constant(1));
1022 fail();
1023 } catch (NullPointerException expected) {
1024 }
1025 }
1026
1027
1028 public void testUniqueIndexNullKey() {
1029 List<String> oneStringList = Lists.newArrayList("foo");
1030 try {
1031 Maps.uniqueIndex(oneStringList, Functions.constant(null));
1032 fail();
1033 } catch (NullPointerException expected) {
1034 }
1035 }
1036
1037 @GwtIncompatible("Maps.fromProperties")
1038 @SuppressWarnings("deprecation")
1039 public void testFromProperties() throws IOException {
1040 Properties testProp = new Properties();
1041
1042 Map<String, String> result = Maps.fromProperties(testProp);
1043 assertTrue(result.isEmpty());
1044 testProp.setProperty("first", "true");
1045
1046 result = Maps.fromProperties(testProp);
1047 assertEquals("true", result.get("first"));
1048 assertEquals(1, result.size());
1049 testProp.setProperty("second", "null");
1050
1051 result = Maps.fromProperties(testProp);
1052 assertEquals("true", result.get("first"));
1053 assertEquals("null", result.get("second"));
1054 assertEquals(2, result.size());
1055
1056
1057 String props = "test\n second = 2\n Third item : a short phrase ";
1058
1059 testProp.load(new StringReader(props));
1060
1061 result = Maps.fromProperties(testProp);
1062 assertEquals(4, result.size());
1063 assertEquals("true", result.get("first"));
1064 assertEquals("", result.get("test"));
1065 assertEquals("2", result.get("second"));
1066 assertEquals("item : a short phrase ", result.get("Third"));
1067 assertFalse(result.containsKey("not here"));
1068
1069
1070 result = Maps.fromProperties(System.getProperties());
1071 assertTrue(result.containsKey("java.version"));
1072
1073
1074 testProp = new Properties(System.getProperties());
1075 String override = "test\njava.version : hidden";
1076
1077 testProp.load(new StringReader(override));
1078
1079 result = Maps.fromProperties(testProp);
1080 assertTrue(result.size() > 2);
1081 assertEquals("", result.get("test"));
1082 assertEquals("hidden", result.get("java.version"));
1083 assertNotSame(System.getProperty("java.version"),
1084 result.get("java.version"));
1085 }
1086
1087 @GwtIncompatible("Maps.fromProperties")
1088 @SuppressWarnings("serial")
1089 public void testFromPropertiesNullKey() {
1090 Properties properties = new Properties() {
1091 @Override public Enumeration<?> propertyNames() {
1092 return Iterators.asEnumeration(
1093 Arrays.asList(null, "first", "second").iterator());
1094 }
1095 };
1096 properties.setProperty("first", "true");
1097 properties.setProperty("second", "null");
1098
1099 try {
1100 Maps.fromProperties(properties);
1101 fail();
1102 } catch (NullPointerException expected) {}
1103 }
1104
1105 @GwtIncompatible("Maps.fromProperties")
1106 @SuppressWarnings("serial")
1107 public void testFromPropertiesNonStringKeys() {
1108 Properties properties = new Properties() {
1109 @Override public Enumeration<?> propertyNames() {
1110 return Iterators.asEnumeration(
1111 Arrays.<Object>asList(Integer.valueOf(123), "first").iterator());
1112 }
1113 };
1114
1115 try {
1116 Maps.fromProperties(properties);
1117 fail();
1118 } catch (ClassCastException expected) {}
1119 }
1120
1121 public void testAsConverter_nominal() throws Exception {
1122 ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
1123 "one", 1,
1124 "two", 2);
1125 Converter<String, Integer> converter = Maps.asConverter(biMap);
1126 for (Entry<String, Integer> entry : biMap.entrySet()) {
1127 assertSame(entry.getValue(), converter.convert(entry.getKey()));
1128 }
1129 }
1130
1131 public void testAsConverter_inverse() throws Exception {
1132 ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
1133 "one", 1,
1134 "two", 2);
1135 Converter<String, Integer> converter = Maps.asConverter(biMap);
1136 for (Entry<String, Integer> entry : biMap.entrySet()) {
1137 assertSame(entry.getKey(), converter.reverse().convert(entry.getValue()));
1138 }
1139 }
1140
1141 public void testAsConverter_noMapping() throws Exception {
1142 ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
1143 "one", 1,
1144 "two", 2);
1145 Converter<String, Integer> converter = Maps.asConverter(biMap);
1146 try {
1147 converter.convert("three");
1148 fail();
1149 } catch (IllegalArgumentException expected) {
1150 }
1151 }
1152
1153 public void testAsConverter_nullConversions() throws Exception {
1154 ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
1155 "one", 1,
1156 "two", 2);
1157 Converter<String, Integer> converter = Maps.asConverter(biMap);
1158 assertNull(converter.convert(null));
1159 assertNull(converter.reverse().convert(null));
1160 }
1161
1162 public void testAsConverter_isAView() throws Exception {
1163 BiMap<String, Integer> biMap = HashBiMap.create();
1164 biMap.put("one", 1);
1165 biMap.put("two", 2);
1166 Converter<String, Integer> converter = Maps.asConverter(biMap);
1167
1168 assertSame(1, converter.convert("one"));
1169 assertSame(2, converter.convert("two"));
1170 try {
1171 converter.convert("three");
1172 fail();
1173 } catch (IllegalArgumentException expected) {
1174 }
1175
1176 biMap.put("three", 3);
1177
1178 assertSame(1, converter.convert("one"));
1179 assertSame(2, converter.convert("two"));
1180 assertSame(3, converter.convert("three"));
1181 }
1182
1183 public void testAsConverter_withNullMapping() throws Exception {
1184 BiMap<String, Integer> biMap = HashBiMap.create();
1185 biMap.put("one", 1);
1186 biMap.put("two", 2);
1187 biMap.put("three", null);
1188 try {
1189 Maps.asConverter(biMap).convert("three");
1190 fail();
1191 } catch (IllegalArgumentException expected) {
1192 }
1193 }
1194
1195 public void testAsConverter_toString() {
1196 ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
1197 "one", 1,
1198 "two", 2);
1199 Converter<String, Integer> converter = Maps.asConverter(biMap);
1200 assertEquals("Maps.asConverter({one=1, two=2})", converter.toString());
1201 }
1202
1203 public void testAsConverter_serialization() {
1204 ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
1205 "one", 1,
1206 "two", 2);
1207 Converter<String, Integer> converter = Maps.asConverter(biMap);
1208 SerializableTester.reserializeAndAssert(converter);
1209 }
1210
1211 public void testUnmodifiableBiMap() {
1212 BiMap<Integer, String> mod = HashBiMap.create();
1213 mod.put(1, "one");
1214 mod.put(2, "two");
1215 mod.put(3, "three");
1216
1217 BiMap<Number, String> unmod = Maps.<Number, String>unmodifiableBiMap(mod);
1218
1219
1220 assertSame(unmod.inverse(), unmod.inverse());
1221 assertSame(unmod, unmod.inverse().inverse());
1222
1223
1224 mod.put(4, "four");
1225 assertEquals(true, unmod.get(4).equals("four"));
1226 assertEquals(true, unmod.inverse().get("four").equals(4));
1227
1228
1229 try {
1230 unmod.put(4, "four");
1231 fail("UnsupportedOperationException expected");
1232 } catch (UnsupportedOperationException expected) {}
1233 try {
1234 unmod.forcePut(4, "four");
1235 fail("UnsupportedOperationException expected");
1236 } catch (UnsupportedOperationException expected) {}
1237 try {
1238 unmod.putAll(Collections.singletonMap(4, "four"));
1239 fail("UnsupportedOperationException expected");
1240 } catch (UnsupportedOperationException expected) {}
1241
1242
1243 BiMap<String, Number> inverse = unmod.inverse();
1244 try {
1245 inverse.put("four", 4);
1246 fail("UnsupportedOperationException expected");
1247 } catch (UnsupportedOperationException expected) {}
1248 try {
1249 inverse.forcePut("four", 4);
1250 fail("UnsupportedOperationException expected");
1251 } catch (UnsupportedOperationException expected) {}
1252 try {
1253 inverse.putAll(Collections.singletonMap("four", 4));
1254 fail("UnsupportedOperationException expected");
1255 } catch (UnsupportedOperationException expected) {}
1256 Set<String> values = unmod.values();
1257 try {
1258 values.remove("four");
1259 fail("UnsupportedOperationException expected");
1260 } catch (UnsupportedOperationException expected) {}
1261 Set<Map.Entry<Number, String>> entries = unmod.entrySet();
1262 Map.Entry<Number, String> entry = entries.iterator().next();
1263 try {
1264 entry.setValue("four");
1265 fail("UnsupportedOperationException expected");
1266 } catch (UnsupportedOperationException expected) {}
1267 @SuppressWarnings("unchecked")
1268 Map.Entry<Integer, String> entry2
1269 = (Map.Entry<Integer, String>) entries.toArray()[0];
1270 try {
1271 entry2.setValue("four");
1272 fail("UnsupportedOperationException expected");
1273 } catch (UnsupportedOperationException expected) {}
1274 }
1275
1276 public void testImmutableEntry() {
1277 Map.Entry<String, Integer> e = Maps.immutableEntry("foo", 1);
1278 assertEquals("foo", e.getKey());
1279 assertEquals(1, (int) e.getValue());
1280 try {
1281 e.setValue(2);
1282 fail("UnsupportedOperationException expected");
1283 } catch (UnsupportedOperationException expected) {}
1284 assertEquals("foo=1", e.toString());
1285 assertEquals(101575, e.hashCode());
1286 }
1287
1288 public void testImmutableEntryNull() {
1289 Map.Entry<String, Integer> e
1290 = Maps.immutableEntry((String) null, (Integer) null);
1291 assertNull(e.getKey());
1292 assertNull(e.getValue());
1293 try {
1294 e.setValue(null);
1295 fail("UnsupportedOperationException expected");
1296 } catch (UnsupportedOperationException expected) {}
1297 assertEquals("null=null", e.toString());
1298 assertEquals(0, e.hashCode());
1299 }
1300
1301
1302 public void testSynchronizedBiMap() {
1303 BiMap<String, Integer> bimap = HashBiMap.create();
1304 bimap.put("one", 1);
1305 BiMap<String, Integer> sync = Maps.synchronizedBiMap(bimap);
1306 bimap.put("two", 2);
1307 sync.put("three", 3);
1308 assertEquals(ImmutableSet.of(1, 2, 3), bimap.inverse().keySet());
1309 assertEquals(ImmutableSet.of(1, 2, 3), sync.inverse().keySet());
1310 }
1311
1312 private static final Predicate<String> NOT_LENGTH_3
1313 = new Predicate<String>() {
1314 @Override
1315 public boolean apply(String input) {
1316 return input == null || input.length() != 3;
1317 }
1318 };
1319
1320 private static final Predicate<Integer> EVEN
1321 = new Predicate<Integer>() {
1322 @Override
1323 public boolean apply(Integer input) {
1324 return input == null || input % 2 == 0;
1325 }
1326 };
1327
1328 private static final Predicate<Entry<String, Integer>> CORRECT_LENGTH
1329 = new Predicate<Entry<String, Integer>>() {
1330 @Override
1331 public boolean apply(Entry<String, Integer> input) {
1332 return input.getKey().length() == input.getValue();
1333 }
1334 };
1335
1336 private static final Function<Integer, Double> SQRT_FUNCTION = new Function<Integer, Double>() {
1337 @Override
1338 public Double apply(Integer in) {
1339 return Math.sqrt(in);
1340 }
1341 };
1342
1343 public static class FilteredMapTest extends TestCase {
1344 Map<String, Integer> createUnfiltered() {
1345 return Maps.newHashMap();
1346 }
1347
1348 public void testFilteredKeysIllegalPut() {
1349 Map<String, Integer> unfiltered = createUnfiltered();
1350 Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
1351 filtered.put("a", 1);
1352 filtered.put("b", 2);
1353 assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
1354
1355 try {
1356 filtered.put("yyy", 3);
1357 fail();
1358 } catch (IllegalArgumentException expected) {}
1359 }
1360
1361 public void testFilteredKeysIllegalPutAll() {
1362 Map<String, Integer> unfiltered = createUnfiltered();
1363 Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
1364 filtered.put("a", 1);
1365 filtered.put("b", 2);
1366 assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
1367
1368 try {
1369 filtered.putAll(ImmutableMap.of("c", 3, "zzz", 4, "b", 5));
1370 fail();
1371 } catch (IllegalArgumentException expected) {}
1372
1373 assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
1374 }
1375
1376 public void testFilteredKeysFilteredReflectsBackingChanges() {
1377 Map<String, Integer> unfiltered = createUnfiltered();
1378 Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
1379 unfiltered.put("two", 2);
1380 unfiltered.put("three", 3);
1381 unfiltered.put("four", 4);
1382 assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
1383 assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
1384
1385 unfiltered.remove("three");
1386 assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
1387 assertEquals(ImmutableMap.of("four", 4), filtered);
1388
1389 unfiltered.clear();
1390 assertEquals(ImmutableMap.of(), unfiltered);
1391 assertEquals(ImmutableMap.of(), filtered);
1392 }
1393
1394 public void testFilteredValuesIllegalPut() {
1395 Map<String, Integer> unfiltered = createUnfiltered();
1396 Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
1397 filtered.put("a", 2);
1398 unfiltered.put("b", 4);
1399 unfiltered.put("c", 5);
1400 assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
1401
1402 try {
1403 filtered.put("yyy", 3);
1404 fail();
1405 } catch (IllegalArgumentException expected) {}
1406 assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
1407 }
1408
1409 public void testFilteredValuesIllegalPutAll() {
1410 Map<String, Integer> unfiltered = createUnfiltered();
1411 Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
1412 filtered.put("a", 2);
1413 unfiltered.put("b", 4);
1414 unfiltered.put("c", 5);
1415 assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
1416
1417 try {
1418 filtered.putAll(ImmutableMap.of("c", 4, "zzz", 5, "b", 6));
1419 fail();
1420 } catch (IllegalArgumentException expected) {}
1421 assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
1422 }
1423
1424 public void testFilteredValuesIllegalSetValue() {
1425 Map<String, Integer> unfiltered = createUnfiltered();
1426 Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
1427 filtered.put("a", 2);
1428 filtered.put("b", 4);
1429 assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
1430
1431 Entry<String, Integer> entry = filtered.entrySet().iterator().next();
1432 try {
1433 entry.setValue(5);
1434 fail();
1435 } catch (IllegalArgumentException expected) {}
1436
1437 assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
1438 }
1439
1440 public void testFilteredValuesClear() {
1441 Map<String, Integer> unfiltered = createUnfiltered();
1442 unfiltered.put("one", 1);
1443 unfiltered.put("two", 2);
1444 unfiltered.put("three", 3);
1445 unfiltered.put("four", 4);
1446 Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
1447 assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4),
1448 unfiltered);
1449 assertEquals(ImmutableMap.of("two", 2, "four", 4), filtered);
1450
1451 filtered.clear();
1452 assertEquals(ImmutableMap.of("one", 1, "three", 3), unfiltered);
1453 assertTrue(filtered.isEmpty());
1454 }
1455
1456 public void testFilteredEntriesIllegalPut() {
1457 Map<String, Integer> unfiltered = createUnfiltered();
1458 unfiltered.put("cat", 3);
1459 unfiltered.put("dog", 2);
1460 unfiltered.put("horse", 5);
1461 Map<String, Integer> filtered
1462 = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
1463 assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
1464
1465 filtered.put("chicken", 7);
1466 assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
1467
1468 try {
1469 filtered.put("cow", 7);
1470 fail();
1471 } catch (IllegalArgumentException expected) {}
1472 assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
1473 }
1474
1475 public void testFilteredEntriesIllegalPutAll() {
1476 Map<String, Integer> unfiltered = createUnfiltered();
1477 unfiltered.put("cat", 3);
1478 unfiltered.put("dog", 2);
1479 unfiltered.put("horse", 5);
1480 Map<String, Integer> filtered
1481 = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
1482 assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
1483
1484 filtered.put("chicken", 7);
1485 assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
1486
1487 try {
1488 filtered.putAll(ImmutableMap.of("sheep", 5, "cow", 7));
1489 fail();
1490 } catch (IllegalArgumentException expected) {}
1491 assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
1492 }
1493
1494 public void testFilteredEntriesObjectPredicate() {
1495 Map<String, Integer> unfiltered = createUnfiltered();
1496 unfiltered.put("cat", 3);
1497 unfiltered.put("dog", 2);
1498 unfiltered.put("horse", 5);
1499 Predicate<Object> predicate = Predicates.alwaysFalse();
1500 Map<String, Integer> filtered
1501 = Maps.filterEntries(unfiltered, predicate);
1502 assertTrue(filtered.isEmpty());
1503 }
1504
1505 public void testFilteredEntriesWildCardEntryPredicate() {
1506 Map<String, Integer> unfiltered = createUnfiltered();
1507 unfiltered.put("cat", 3);
1508 unfiltered.put("dog", 2);
1509 unfiltered.put("horse", 5);
1510 Predicate<Entry<?, ?>> predicate = new Predicate<Entry<?, ?>>() {
1511 @Override
1512 public boolean apply(Entry<?, ?> input) {
1513 return "cat".equals(input.getKey())
1514 || Integer.valueOf(2) == input.getValue();
1515 }
1516 };
1517 Map<String, Integer> filtered
1518 = Maps.filterEntries(unfiltered, predicate);
1519 assertEquals(ImmutableMap.of("cat", 3, "dog", 2), filtered);
1520 }
1521 }
1522
1523 public static class FilteredSortedMapTest extends FilteredMapTest {
1524 @Override
1525 SortedMap<String, Integer> createUnfiltered() {
1526 return Maps.newTreeMap();
1527 }
1528
1529 public void testFilterKeysIdentifiesSortedMap() {
1530 SortedMap<String, Integer> map = createUnfiltered();
1531 assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
1532 instanceof SortedMap);
1533 }
1534
1535 public void testFilterValuesIdentifiesSortedMap() {
1536 SortedMap<String, Integer> map = createUnfiltered();
1537 assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
1538 instanceof SortedMap);
1539 }
1540
1541 public void testFilterEntriesIdentifiesSortedMap() {
1542 SortedMap<String, Integer> map = createUnfiltered();
1543 assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
1544 instanceof SortedMap);
1545 }
1546
1547 public void testFirstAndLastKeyFilteredMap() {
1548 SortedMap<String, Integer> unfiltered = createUnfiltered();
1549 unfiltered.put("apple", 2);
1550 unfiltered.put("banana", 6);
1551 unfiltered.put("cat", 3);
1552 unfiltered.put("dog", 5);
1553
1554 SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
1555 assertEquals("banana", filtered.firstKey());
1556 assertEquals("cat", filtered.lastKey());
1557 }
1558
1559 public void testHeadSubTailMap_FilteredMap() {
1560 SortedMap<String, Integer> unfiltered = createUnfiltered();
1561 unfiltered.put("apple", 2);
1562 unfiltered.put("banana", 6);
1563 unfiltered.put("cat", 4);
1564 unfiltered.put("dog", 3);
1565 SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
1566
1567 assertEquals(ImmutableMap.of("banana", 6), filtered.headMap("dog"));
1568 assertEquals(ImmutableMap.of(), filtered.headMap("banana"));
1569 assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.headMap("emu"));
1570
1571 assertEquals(ImmutableMap.of("banana", 6), filtered.subMap("banana", "dog"));
1572 assertEquals(ImmutableMap.of("dog", 3), filtered.subMap("cat", "emu"));
1573
1574 assertEquals(ImmutableMap.of("dog", 3), filtered.tailMap("cat"));
1575 assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.tailMap("banana"));
1576 }
1577 }
1578
1579 public static class FilteredBiMapTest extends FilteredMapTest {
1580 @Override
1581 BiMap<String, Integer> createUnfiltered() {
1582 return HashBiMap.create();
1583 }
1584
1585 public void testFilterKeysIdentifiesBiMap() {
1586 BiMap<String, Integer> map = createUnfiltered();
1587 assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
1588 instanceof BiMap);
1589 }
1590
1591 public void testFilterValuesIdentifiesBiMap() {
1592 BiMap<String, Integer> map = createUnfiltered();
1593 assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
1594 instanceof BiMap);
1595 }
1596
1597 public void testFilterEntriesIdentifiesBiMap() {
1598 BiMap<String, Integer> map = createUnfiltered();
1599 assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
1600 instanceof BiMap);
1601 }
1602 }
1603
1604 public void testTransformValues() {
1605 Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9);
1606 Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
1607
1608 assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
1609 }
1610
1611 public void testTransformValuesSecretlySorted() {
1612 Map<String, Integer> map =
1613 sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
1614 Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
1615
1616 assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
1617 assertTrue(transformed instanceof SortedMap);
1618 }
1619
1620 @GwtIncompatible("NavigableMap")
1621 public void testTransformValuesSecretlyNavigable() {
1622 Map<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
1623 Map<String, Double> transformed;
1624
1625 transformed = transformValues(map, SQRT_FUNCTION);
1626 assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
1627 assertTrue(transformed instanceof NavigableMap);
1628
1629 transformed =
1630 transformValues((SortedMap<String, Integer>) map, SQRT_FUNCTION);
1631 assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
1632 assertTrue(transformed instanceof NavigableMap);
1633 }
1634
1635 public void testTransformEntries() {
1636 Map<String, String> map = ImmutableMap.of("a", "4", "b", "9");
1637 EntryTransformer<String, String, String> concat =
1638 new EntryTransformer<String, String, String>() {
1639 @Override
1640 public String transformEntry(String key, String value) {
1641 return key + value;
1642 }
1643 };
1644 Map<String, String> transformed = transformEntries(map, concat);
1645
1646 assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
1647 }
1648
1649 public void testTransformEntriesSecretlySorted() {
1650 Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
1651 EntryTransformer<String, String, String> concat =
1652 new EntryTransformer<String, String, String>() {
1653 @Override
1654 public String transformEntry(String key, String value) {
1655 return key + value;
1656 }
1657 };
1658 Map<String, String> transformed = transformEntries(map, concat);
1659
1660 assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
1661 assertTrue(transformed instanceof SortedMap);
1662 }
1663
1664 @GwtIncompatible("NavigableMap")
1665 public void testTransformEntriesSecretlyNavigable() {
1666 Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
1667 EntryTransformer<String, String, String> concat =
1668 new EntryTransformer<String, String, String>() {
1669 @Override
1670 public String transformEntry(String key, String value) {
1671 return key + value;
1672 }
1673 };
1674 Map<String, String> transformed;
1675
1676 transformed = transformEntries(map, concat);
1677 assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
1678 assertTrue(transformed instanceof NavigableMap);
1679
1680 transformed = transformEntries((SortedMap<String, String>) map, concat);
1681 assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
1682 assertTrue(transformed instanceof NavigableMap);
1683 }
1684
1685 @SuppressWarnings("unused")
1686 public void testTransformEntriesGenerics() {
1687 Map<Object, Object> map1 = ImmutableMap.<Object, Object>of(1, 2);
1688 Map<Object, Number> map2 = ImmutableMap.<Object, Number>of(1, 2);
1689 Map<Object, Integer> map3 = ImmutableMap.<Object, Integer>of(1, 2);
1690 Map<Number, Object> map4 = ImmutableMap.<Number, Object>of(1, 2);
1691 Map<Number, Number> map5 = ImmutableMap.<Number, Number>of(1, 2);
1692 Map<Number, Integer> map6 = ImmutableMap.<Number, Integer>of(1, 2);
1693 Map<Integer, Object> map7 = ImmutableMap.<Integer, Object>of(1, 2);
1694 Map<Integer, Number> map8 = ImmutableMap.<Integer, Number>of(1, 2);
1695 Map<Integer, Integer> map9 = ImmutableMap.<Integer, Integer>of(1, 2);
1696 Map<? extends Number, ? extends Number> map0 = ImmutableMap.of(1, 2);
1697
1698 EntryTransformer<Number, Number, Double> transformer =
1699 new EntryTransformer<Number, Number, Double>() {
1700 @Override
1701 public Double transformEntry(Number key, Number value) {
1702 return key.doubleValue() + value.doubleValue();
1703 }
1704 };
1705
1706 Map<Object, Double> objectKeyed;
1707 Map<Number, Double> numberKeyed;
1708 Map<Integer, Double> integerKeyed;
1709
1710 numberKeyed = transformEntries(map5, transformer);
1711 numberKeyed = transformEntries(map6, transformer);
1712 integerKeyed = transformEntries(map8, transformer);
1713 integerKeyed = transformEntries(map9, transformer);
1714
1715 Map<? extends Number, Double> wildcarded = transformEntries(map0, transformer);
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740 }
1741
1742 public void testTransformEntriesExample() {
1743 Map<String, Boolean> options =
1744 ImmutableMap.of("verbose", true, "sort", false);
1745 EntryTransformer<String, Boolean, String> flagPrefixer =
1746 new EntryTransformer<String, Boolean, String>() {
1747 @Override
1748 public String transformEntry(String key, Boolean value) {
1749 return value ? key : "no" + key;
1750 }
1751 };
1752 Map<String, String> transformed = transformEntries(options, flagPrefixer);
1753 assertEquals("{verbose=verbose, sort=nosort}", transformed.toString());
1754 }
1755
1756
1757 private static <K, V> SortedMap<K, V> sortedNotNavigable(
1758 final SortedMap<K, V> map) {
1759 return new ForwardingSortedMap<K, V>() {
1760 @Override protected SortedMap<K, V> delegate() {
1761 return map;
1762 }
1763 };
1764 }
1765
1766 public void testSortedMapTransformValues() {
1767 SortedMap<String, Integer> map =
1768 sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
1769 SortedMap<String, Double> transformed =
1770 transformValues(map, SQRT_FUNCTION);
1771
1772
1773
1774
1775
1776 assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
1777 }
1778
1779 @GwtIncompatible("NavigableMap")
1780 public void testNavigableMapTransformValues() {
1781 NavigableMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
1782 NavigableMap<String, Double> transformed =
1783 transformValues(map, SQRT_FUNCTION);
1784
1785 assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
1786 }
1787
1788 public void testSortedMapTransformEntries() {
1789 SortedMap<String, String> map =
1790 sortedNotNavigable(ImmutableSortedMap.of("a", "4", "b", "9"));
1791 EntryTransformer<String, String, String> concat =
1792 new EntryTransformer<String, String, String>() {
1793 @Override
1794 public String transformEntry(String key, String value) {
1795 return key + value;
1796 }
1797 };
1798 SortedMap<String, String> transformed = transformEntries(map, concat);
1799
1800
1801
1802
1803
1804 assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
1805 }
1806
1807 @GwtIncompatible("NavigableMap")
1808 public void testNavigableMapTransformEntries() {
1809 NavigableMap<String, String> map =
1810 ImmutableSortedMap.of("a", "4", "b", "9");
1811 EntryTransformer<String, String, String> concat =
1812 new EntryTransformer<String, String, String>() {
1813 @Override
1814 public String transformEntry(String key, String value) {
1815 return key + value;
1816 }
1817 };
1818 NavigableMap<String, String> transformed = transformEntries(map, concat);
1819
1820 assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
1821 }
1822
1823 @GwtIncompatible("NavigableMap")
1824 public void testUnmodifiableNavigableMap() {
1825 TreeMap<Integer, String> mod = Maps.newTreeMap();
1826 mod.put(1, "one");
1827 mod.put(2, "two");
1828 mod.put(3, "three");
1829
1830 NavigableMap<Integer, String> unmod = unmodifiableNavigableMap(mod);
1831
1832
1833 mod.put(4, "four");
1834 assertEquals("four", unmod.get(4));
1835 assertEquals("four", unmod.descendingMap().get(4));
1836
1837 ensureNotDirectlyModifiable(unmod);
1838 ensureNotDirectlyModifiable(unmod.descendingMap());
1839 ensureNotDirectlyModifiable(unmod.headMap(2, true));
1840 ensureNotDirectlyModifiable(unmod.subMap(1, true, 3, true));
1841 ensureNotDirectlyModifiable(unmod.tailMap(2, true));
1842
1843 Collection<String> values = unmod.values();
1844 try {
1845 values.add("4");
1846 fail("UnsupportedOperationException expected");
1847 } catch (UnsupportedOperationException expected) {
1848 }
1849 try {
1850 values.remove("four");
1851 fail("UnsupportedOperationException expected");
1852 } catch (UnsupportedOperationException expected) {
1853 }
1854 try {
1855 values.removeAll(Collections.singleton("four"));
1856 fail("UnsupportedOperationException expected");
1857 } catch (UnsupportedOperationException expected) {
1858 }
1859 try {
1860 values.retainAll(Collections.singleton("four"));
1861 fail("UnsupportedOperationException expected");
1862 } catch (UnsupportedOperationException expected) {
1863 }
1864 try {
1865 Iterator<String> iterator = values.iterator();
1866 iterator.next();
1867 iterator.remove();
1868 fail("UnsupportedOperationException expected");
1869 } catch (UnsupportedOperationException expected) {
1870 }
1871
1872 Set<Map.Entry<Integer, String>> entries = unmod.entrySet();
1873 try {
1874 Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
1875 iterator.next();
1876 iterator.remove();
1877 fail("UnsupportedOperationException expected");
1878 } catch (UnsupportedOperationException expected) {
1879 }
1880 Map.Entry<Integer, String> entry = entries.iterator().next();
1881 try {
1882 entry.setValue("four");
1883 fail("UnsupportedOperationException expected");
1884 } catch (UnsupportedOperationException expected) {
1885 }
1886 entry = unmod.lowerEntry(1);
1887 assertNull(entry);
1888 entry = unmod.floorEntry(2);
1889 try {
1890 entry.setValue("four");
1891 fail("UnsupportedOperationException expected");
1892 } catch (UnsupportedOperationException expected) {
1893 }
1894 entry = unmod.ceilingEntry(2);
1895 try {
1896 entry.setValue("four");
1897 fail("UnsupportedOperationException expected");
1898 } catch (UnsupportedOperationException expected) {
1899 }
1900 entry = unmod.lowerEntry(2);
1901 try {
1902 entry.setValue("four");
1903 fail("UnsupportedOperationException expected");
1904 } catch (UnsupportedOperationException expected) {
1905 }
1906 entry = unmod.higherEntry(2);
1907 try {
1908 entry.setValue("four");
1909 fail("UnsupportedOperationException expected");
1910 } catch (UnsupportedOperationException expected) {
1911 }
1912 entry = unmod.firstEntry();
1913 try {
1914 entry.setValue("four");
1915 fail("UnsupportedOperationException expected");
1916 } catch (UnsupportedOperationException expected) {
1917 }
1918 entry = unmod.lastEntry();
1919 try {
1920 entry.setValue("four");
1921 fail("UnsupportedOperationException expected");
1922 } catch (UnsupportedOperationException expected) {
1923 }
1924 @SuppressWarnings("unchecked")
1925 Map.Entry<Integer, String> entry2 =
1926 (Map.Entry<Integer, String>) entries.toArray()[0];
1927 try {
1928 entry2.setValue("four");
1929 fail("UnsupportedOperationException expected");
1930 } catch (UnsupportedOperationException expected) {
1931 }
1932 }
1933
1934 @GwtIncompatible("NavigableMap")
1935 void ensureNotDirectlyModifiable(NavigableMap<Integer, String> unmod) {
1936 try {
1937 unmod.put(4, "four");
1938 fail("UnsupportedOperationException expected");
1939 } catch (UnsupportedOperationException expected) {
1940 }
1941 try {
1942 unmod.putAll(Collections.singletonMap(4, "four"));
1943 fail("UnsupportedOperationException expected");
1944 } catch (UnsupportedOperationException expected) {
1945 }
1946 try {
1947 unmod.remove("four");
1948 fail("UnsupportedOperationException expected");
1949 } catch (UnsupportedOperationException expected) {
1950 }
1951 try {
1952 unmod.pollFirstEntry();
1953 fail("UnsupportedOperationException expected");
1954 } catch (UnsupportedOperationException expected) {
1955 }
1956 try {
1957 unmod.pollLastEntry();
1958 fail("UnsupportedOperationException expected");
1959 } catch (UnsupportedOperationException expected) {
1960 }
1961 }
1962 }