ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentHashMapTest.java
Revision: 1.56
Committed: Wed Aug 23 05:33:00 2017 UTC (6 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.55: +16 -4 lines
Log Message:
8186171: HashMap: Entry.setValue may not work after Iterator.remove() called for previous entries

File Contents

# Content
1 /*
2 * Written by Doug Lea and Martin Buchholz with assistance from
3 * members of JCP JSR-166 Expert Group and released to the public
4 * domain, as explained at
5 * http://creativecommons.org/publicdomain/zero/1.0/
6 * Other contributors include Andrew Wright, Jeffrey Hayes,
7 * Pat Fisher, Mike Judd.
8 */
9
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.Enumeration;
15 import java.util.Iterator;
16 import java.util.Map;
17 import java.util.Random;
18 import java.util.Set;
19 import java.util.concurrent.ConcurrentHashMap;
20
21 import junit.framework.Test;
22
23 public class ConcurrentHashMapTest extends JSR166TestCase {
24 public static void main(String[] args) {
25 main(suite(), args);
26 }
27 public static Test suite() {
28 class Implementation implements MapImplementation {
29 public Class<?> klazz() { return ConcurrentHashMap.class; }
30 public Map emptyMap() { return new ConcurrentHashMap(); }
31 public Object makeKey(int i) { return i; }
32 public Object makeValue(int i) { return i; }
33 public boolean isConcurrent() { return true; }
34 public boolean permitsNullKeys() { return false; }
35 public boolean permitsNullValues() { return false; }
36 public boolean supportsSetValue() { return true; }
37 }
38 return newTestSuite(
39 ConcurrentHashMapTest.class,
40 MapTest.testSuite(new Implementation()));
41 }
42
43 /**
44 * Returns a new map from Integers 1-5 to Strings "A"-"E".
45 */
46 private static ConcurrentHashMap<Integer, String> map5() {
47 ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>(5);
48 assertTrue(map.isEmpty());
49 map.put(one, "A");
50 map.put(two, "B");
51 map.put(three, "C");
52 map.put(four, "D");
53 map.put(five, "E");
54 assertFalse(map.isEmpty());
55 assertEquals(5, map.size());
56 return map;
57 }
58
59 /** Re-implement Integer.compare for old java versions */
60 static int compare(int x, int y) {
61 return (x < y) ? -1 : (x > y) ? 1 : 0;
62 }
63
64 // classes for testing Comparable fallbacks
65 static class BI implements Comparable<BI> {
66 private final int value;
67 BI(int value) { this.value = value; }
68 public int compareTo(BI other) {
69 return compare(value, other.value);
70 }
71 public boolean equals(Object x) {
72 return (x instanceof BI) && ((BI)x).value == value;
73 }
74 public int hashCode() { return 42; }
75 }
76 static class CI extends BI { CI(int value) { super(value); } }
77 static class DI extends BI { DI(int value) { super(value); } }
78
79 static class BS implements Comparable<BS> {
80 private final String value;
81 BS(String value) { this.value = value; }
82 public int compareTo(BS other) {
83 return value.compareTo(other.value);
84 }
85 public boolean equals(Object x) {
86 return (x instanceof BS) && value.equals(((BS)x).value);
87 }
88 public int hashCode() { return 42; }
89 }
90
91 static class LexicographicList<E extends Comparable<E>> extends ArrayList<E>
92 implements Comparable<LexicographicList<E>> {
93 LexicographicList(Collection<E> c) { super(c); }
94 LexicographicList(E e) { super(Collections.singleton(e)); }
95 public int compareTo(LexicographicList<E> other) {
96 int common = Math.min(size(), other.size());
97 int r = 0;
98 for (int i = 0; i < common; i++) {
99 if ((r = get(i).compareTo(other.get(i))) != 0)
100 break;
101 }
102 if (r == 0)
103 r = compare(size(), other.size());
104 return r;
105 }
106 private static final long serialVersionUID = 0;
107 }
108
109 static class CollidingObject {
110 final String value;
111 CollidingObject(final String value) { this.value = value; }
112 public int hashCode() { return this.value.hashCode() & 1; }
113 public boolean equals(final Object obj) {
114 return (obj instanceof CollidingObject) && ((CollidingObject)obj).value.equals(value);
115 }
116 }
117
118 static class ComparableCollidingObject extends CollidingObject implements Comparable<ComparableCollidingObject> {
119 ComparableCollidingObject(final String value) { super(value); }
120 public int compareTo(final ComparableCollidingObject o) {
121 return value.compareTo(o.value);
122 }
123 }
124
125 /**
126 * Inserted elements that are subclasses of the same Comparable
127 * class are found.
128 */
129 public void testComparableFamily() {
130 int size = 500; // makes measured test run time -> 60ms
131 ConcurrentHashMap<BI, Boolean> m =
132 new ConcurrentHashMap<BI, Boolean>();
133 for (int i = 0; i < size; i++) {
134 assertNull(m.put(new CI(i), true));
135 }
136 for (int i = 0; i < size; i++) {
137 assertTrue(m.containsKey(new CI(i)));
138 assertTrue(m.containsKey(new DI(i)));
139 }
140 }
141
142 /**
143 * Elements of classes with erased generic type parameters based
144 * on Comparable can be inserted and found.
145 */
146 public void testGenericComparable() {
147 int size = 120; // makes measured test run time -> 60ms
148 ConcurrentHashMap<Object, Boolean> m =
149 new ConcurrentHashMap<Object, Boolean>();
150 for (int i = 0; i < size; i++) {
151 BI bi = new BI(i);
152 BS bs = new BS(String.valueOf(i));
153 LexicographicList<BI> bis = new LexicographicList<BI>(bi);
154 LexicographicList<BS> bss = new LexicographicList<BS>(bs);
155 assertNull(m.putIfAbsent(bis, true));
156 assertTrue(m.containsKey(bis));
157 if (m.putIfAbsent(bss, true) == null)
158 assertTrue(m.containsKey(bss));
159 assertTrue(m.containsKey(bis));
160 }
161 for (int i = 0; i < size; i++) {
162 assertTrue(m.containsKey(Collections.singletonList(new BI(i))));
163 }
164 }
165
166 /**
167 * Elements of non-comparable classes equal to those of classes
168 * with erased generic type parameters based on Comparable can be
169 * inserted and found.
170 */
171 public void testGenericComparable2() {
172 int size = 500; // makes measured test run time -> 60ms
173 ConcurrentHashMap<Object, Boolean> m =
174 new ConcurrentHashMap<Object, Boolean>();
175 for (int i = 0; i < size; i++) {
176 m.put(Collections.singletonList(new BI(i)), true);
177 }
178
179 for (int i = 0; i < size; i++) {
180 LexicographicList<BI> bis = new LexicographicList<BI>(new BI(i));
181 assertTrue(m.containsKey(bis));
182 }
183 }
184
185 /**
186 * Mixtures of instances of comparable and non-comparable classes
187 * can be inserted and found.
188 */
189 public void testMixedComparable() {
190 int size = 1200; // makes measured test run time -> 35ms
191 ConcurrentHashMap<Object, Object> map =
192 new ConcurrentHashMap<Object, Object>();
193 Random rng = new Random();
194 for (int i = 0; i < size; i++) {
195 Object x;
196 switch (rng.nextInt(4)) {
197 case 0:
198 x = new Object();
199 break;
200 case 1:
201 x = new CollidingObject(Integer.toString(i));
202 break;
203 default:
204 x = new ComparableCollidingObject(Integer.toString(i));
205 }
206 assertNull(map.put(x, x));
207 }
208 int count = 0;
209 for (Object k : map.keySet()) {
210 assertEquals(map.get(k), k);
211 ++count;
212 }
213 assertEquals(count, size);
214 assertEquals(map.size(), size);
215 for (Object k : map.keySet()) {
216 assertEquals(map.put(k, k), k);
217 }
218 }
219
220 /**
221 * clear removes all pairs
222 */
223 public void testClear() {
224 ConcurrentHashMap map = map5();
225 map.clear();
226 assertEquals(0, map.size());
227 }
228
229 /**
230 * Maps with same contents are equal
231 */
232 public void testEquals() {
233 ConcurrentHashMap map1 = map5();
234 ConcurrentHashMap map2 = map5();
235 assertEquals(map1, map2);
236 assertEquals(map2, map1);
237 map1.clear();
238 assertFalse(map1.equals(map2));
239 assertFalse(map2.equals(map1));
240 }
241
242 /**
243 * hashCode() equals sum of each key.hashCode ^ value.hashCode
244 */
245 public void testHashCode() {
246 ConcurrentHashMap<Integer,String> map = map5();
247 int sum = 0;
248 for (Map.Entry<Integer,String> e : map.entrySet())
249 sum += e.getKey().hashCode() ^ e.getValue().hashCode();
250 assertEquals(sum, map.hashCode());
251 }
252
253 /**
254 * contains returns true for contained value
255 */
256 public void testContains() {
257 ConcurrentHashMap map = map5();
258 assertTrue(map.contains("A"));
259 assertFalse(map.contains("Z"));
260 }
261
262 /**
263 * containsKey returns true for contained key
264 */
265 public void testContainsKey() {
266 ConcurrentHashMap map = map5();
267 assertTrue(map.containsKey(one));
268 assertFalse(map.containsKey(zero));
269 }
270
271 /**
272 * containsValue returns true for held values
273 */
274 public void testContainsValue() {
275 ConcurrentHashMap map = map5();
276 assertTrue(map.containsValue("A"));
277 assertFalse(map.containsValue("Z"));
278 }
279
280 /**
281 * enumeration returns an enumeration containing the correct
282 * elements
283 */
284 public void testEnumeration() {
285 ConcurrentHashMap map = map5();
286 Enumeration e = map.elements();
287 int count = 0;
288 while (e.hasMoreElements()) {
289 count++;
290 e.nextElement();
291 }
292 assertEquals(5, count);
293 }
294
295 /**
296 * get returns the correct element at the given key,
297 * or null if not present
298 */
299 public void testGet() {
300 ConcurrentHashMap map = map5();
301 assertEquals("A", (String)map.get(one));
302 ConcurrentHashMap empty = new ConcurrentHashMap();
303 assertNull(map.get("anything"));
304 assertNull(empty.get("anything"));
305 }
306
307 /**
308 * isEmpty is true of empty map and false for non-empty
309 */
310 public void testIsEmpty() {
311 ConcurrentHashMap empty = new ConcurrentHashMap();
312 ConcurrentHashMap map = map5();
313 assertTrue(empty.isEmpty());
314 assertFalse(map.isEmpty());
315 }
316
317 /**
318 * keys returns an enumeration containing all the keys from the map
319 */
320 public void testKeys() {
321 ConcurrentHashMap map = map5();
322 Enumeration e = map.keys();
323 int count = 0;
324 while (e.hasMoreElements()) {
325 count++;
326 e.nextElement();
327 }
328 assertEquals(5, count);
329 }
330
331 /**
332 * keySet returns a Set containing all the keys
333 */
334 public void testKeySet() {
335 ConcurrentHashMap map = map5();
336 Set s = map.keySet();
337 assertEquals(5, s.size());
338 assertTrue(s.contains(one));
339 assertTrue(s.contains(two));
340 assertTrue(s.contains(three));
341 assertTrue(s.contains(four));
342 assertTrue(s.contains(five));
343 }
344
345 /**
346 * Test keySet().removeAll on empty map
347 */
348 public void testKeySet_empty_removeAll() {
349 ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
350 Set<Integer> set = map.keySet();
351 set.removeAll(Collections.emptyList());
352 assertTrue(map.isEmpty());
353 assertTrue(set.isEmpty());
354 // following is test for JDK-8163353
355 set.removeAll(Collections.emptySet());
356 assertTrue(map.isEmpty());
357 assertTrue(set.isEmpty());
358 }
359
360 /**
361 * keySet.toArray returns contains all keys
362 */
363 public void testKeySetToArray() {
364 ConcurrentHashMap map = map5();
365 Set s = map.keySet();
366 Object[] ar = s.toArray();
367 assertTrue(s.containsAll(Arrays.asList(ar)));
368 assertEquals(5, ar.length);
369 ar[0] = m10;
370 assertFalse(s.containsAll(Arrays.asList(ar)));
371 }
372
373 /**
374 * Values.toArray contains all values
375 */
376 public void testValuesToArray() {
377 ConcurrentHashMap map = map5();
378 Collection v = map.values();
379 Object[] ar = v.toArray();
380 ArrayList s = new ArrayList(Arrays.asList(ar));
381 assertEquals(5, ar.length);
382 assertTrue(s.contains("A"));
383 assertTrue(s.contains("B"));
384 assertTrue(s.contains("C"));
385 assertTrue(s.contains("D"));
386 assertTrue(s.contains("E"));
387 }
388
389 /**
390 * entrySet.toArray contains all entries
391 */
392 public void testEntrySetToArray() {
393 ConcurrentHashMap map = map5();
394 Set s = map.entrySet();
395 Object[] ar = s.toArray();
396 assertEquals(5, ar.length);
397 for (int i = 0; i < 5; ++i) {
398 assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
399 assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
400 }
401 }
402
403 /**
404 * values collection contains all values
405 */
406 public void testValues() {
407 ConcurrentHashMap map = map5();
408 Collection s = map.values();
409 assertEquals(5, s.size());
410 assertTrue(s.contains("A"));
411 assertTrue(s.contains("B"));
412 assertTrue(s.contains("C"));
413 assertTrue(s.contains("D"));
414 assertTrue(s.contains("E"));
415 }
416
417 /**
418 * entrySet contains all pairs
419 */
420 public void testEntrySet() {
421 ConcurrentHashMap map = map5();
422 Set s = map.entrySet();
423 assertEquals(5, s.size());
424 Iterator it = s.iterator();
425 while (it.hasNext()) {
426 Map.Entry e = (Map.Entry) it.next();
427 assertTrue(
428 (e.getKey().equals(one) && e.getValue().equals("A")) ||
429 (e.getKey().equals(two) && e.getValue().equals("B")) ||
430 (e.getKey().equals(three) && e.getValue().equals("C")) ||
431 (e.getKey().equals(four) && e.getValue().equals("D")) ||
432 (e.getKey().equals(five) && e.getValue().equals("E")));
433 }
434 }
435
436 /**
437 * putAll adds all key-value pairs from the given map
438 */
439 public void testPutAll() {
440 ConcurrentHashMap empty = new ConcurrentHashMap();
441 ConcurrentHashMap map = map5();
442 empty.putAll(map);
443 assertEquals(5, empty.size());
444 assertTrue(empty.containsKey(one));
445 assertTrue(empty.containsKey(two));
446 assertTrue(empty.containsKey(three));
447 assertTrue(empty.containsKey(four));
448 assertTrue(empty.containsKey(five));
449 }
450
451 /**
452 * putIfAbsent works when the given key is not present
453 */
454 public void testPutIfAbsent() {
455 ConcurrentHashMap map = map5();
456 map.putIfAbsent(six, "Z");
457 assertTrue(map.containsKey(six));
458 }
459
460 /**
461 * putIfAbsent does not add the pair if the key is already present
462 */
463 public void testPutIfAbsent2() {
464 ConcurrentHashMap map = map5();
465 assertEquals("A", map.putIfAbsent(one, "Z"));
466 }
467
468 /**
469 * replace fails when the given key is not present
470 */
471 public void testReplace() {
472 ConcurrentHashMap map = map5();
473 assertNull(map.replace(six, "Z"));
474 assertFalse(map.containsKey(six));
475 }
476
477 /**
478 * replace succeeds if the key is already present
479 */
480 public void testReplace2() {
481 ConcurrentHashMap map = map5();
482 assertNotNull(map.replace(one, "Z"));
483 assertEquals("Z", map.get(one));
484 }
485
486 /**
487 * replace value fails when the given key not mapped to expected value
488 */
489 public void testReplaceValue() {
490 ConcurrentHashMap map = map5();
491 assertEquals("A", map.get(one));
492 assertFalse(map.replace(one, "Z", "Z"));
493 assertEquals("A", map.get(one));
494 }
495
496 /**
497 * replace value succeeds when the given key mapped to expected value
498 */
499 public void testReplaceValue2() {
500 ConcurrentHashMap map = map5();
501 assertEquals("A", map.get(one));
502 assertTrue(map.replace(one, "A", "Z"));
503 assertEquals("Z", map.get(one));
504 }
505
506 /**
507 * remove removes the correct key-value pair from the map
508 */
509 public void testRemove() {
510 ConcurrentHashMap map = map5();
511 map.remove(five);
512 assertEquals(4, map.size());
513 assertFalse(map.containsKey(five));
514 }
515
516 /**
517 * remove(key,value) removes only if pair present
518 */
519 public void testRemove2() {
520 ConcurrentHashMap map = map5();
521 map.remove(five, "E");
522 assertEquals(4, map.size());
523 assertFalse(map.containsKey(five));
524 map.remove(four, "A");
525 assertEquals(4, map.size());
526 assertTrue(map.containsKey(four));
527 }
528
529 /**
530 * size returns the correct values
531 */
532 public void testSize() {
533 ConcurrentHashMap map = map5();
534 ConcurrentHashMap empty = new ConcurrentHashMap();
535 assertEquals(0, empty.size());
536 assertEquals(5, map.size());
537 }
538
539 /**
540 * toString contains toString of elements
541 */
542 public void testToString() {
543 ConcurrentHashMap map = map5();
544 String s = map.toString();
545 for (int i = 1; i <= 5; ++i) {
546 assertTrue(s.contains(String.valueOf(i)));
547 }
548 }
549
550 // Exception tests
551
552 /**
553 * Cannot create with only negative capacity
554 */
555 public void testConstructor1() {
556 try {
557 new ConcurrentHashMap(-1);
558 shouldThrow();
559 } catch (IllegalArgumentException success) {}
560 }
561
562 /**
563 * Constructor (initialCapacity, loadFactor) throws
564 * IllegalArgumentException if either argument is negative
565 */
566 public void testConstructor2() {
567 try {
568 new ConcurrentHashMap(-1, .75f);
569 shouldThrow();
570 } catch (IllegalArgumentException success) {}
571
572 try {
573 new ConcurrentHashMap(16, -1);
574 shouldThrow();
575 } catch (IllegalArgumentException success) {}
576 }
577
578 /**
579 * Constructor (initialCapacity, loadFactor, concurrencyLevel)
580 * throws IllegalArgumentException if any argument is negative
581 */
582 public void testConstructor3() {
583 try {
584 new ConcurrentHashMap(-1, .75f, 1);
585 shouldThrow();
586 } catch (IllegalArgumentException success) {}
587
588 try {
589 new ConcurrentHashMap(16, -1, 1);
590 shouldThrow();
591 } catch (IllegalArgumentException success) {}
592
593 try {
594 new ConcurrentHashMap(16, .75f, -1);
595 shouldThrow();
596 } catch (IllegalArgumentException success) {}
597 }
598
599 /**
600 * ConcurrentHashMap(map) throws NullPointerException if the given
601 * map is null
602 */
603 public void testConstructor4() {
604 try {
605 new ConcurrentHashMap(null);
606 shouldThrow();
607 } catch (NullPointerException success) {}
608 }
609
610 /**
611 * ConcurrentHashMap(map) creates a new map with the same mappings
612 * as the given map
613 */
614 public void testConstructor5() {
615 ConcurrentHashMap map1 = map5();
616 ConcurrentHashMap map2 = new ConcurrentHashMap(map5());
617 assertTrue(map2.equals(map1));
618 map2.put(one, "F");
619 assertFalse(map2.equals(map1));
620 }
621
622 /**
623 * get(null) throws NPE
624 */
625 public void testGet_NullPointerException() {
626 ConcurrentHashMap c = new ConcurrentHashMap(5);
627 try {
628 c.get(null);
629 shouldThrow();
630 } catch (NullPointerException success) {}
631 }
632
633 /**
634 * containsKey(null) throws NPE
635 */
636 public void testContainsKey_NullPointerException() {
637 ConcurrentHashMap c = new ConcurrentHashMap(5);
638 try {
639 c.containsKey(null);
640 shouldThrow();
641 } catch (NullPointerException success) {}
642 }
643
644 /**
645 * containsValue(null) throws NPE
646 */
647 public void testContainsValue_NullPointerException() {
648 ConcurrentHashMap c = new ConcurrentHashMap(5);
649 try {
650 c.containsValue(null);
651 shouldThrow();
652 } catch (NullPointerException success) {}
653 }
654
655 /**
656 * contains(null) throws NPE
657 */
658 public void testContains_NullPointerException() {
659 ConcurrentHashMap c = new ConcurrentHashMap(5);
660 try {
661 c.contains(null);
662 shouldThrow();
663 } catch (NullPointerException success) {}
664 }
665
666 /**
667 * put(null,x) throws NPE
668 */
669 public void testPut1_NullPointerException() {
670 ConcurrentHashMap c = new ConcurrentHashMap(5);
671 try {
672 c.put(null, "whatever");
673 shouldThrow();
674 } catch (NullPointerException success) {}
675 }
676
677 /**
678 * put(x, null) throws NPE
679 */
680 public void testPut2_NullPointerException() {
681 ConcurrentHashMap c = new ConcurrentHashMap(5);
682 try {
683 c.put("whatever", null);
684 shouldThrow();
685 } catch (NullPointerException success) {}
686 }
687
688 /**
689 * putIfAbsent(null, x) throws NPE
690 */
691 public void testPutIfAbsent1_NullPointerException() {
692 ConcurrentHashMap c = new ConcurrentHashMap(5);
693 try {
694 c.putIfAbsent(null, "whatever");
695 shouldThrow();
696 } catch (NullPointerException success) {}
697 }
698
699 /**
700 * replace(null, x) throws NPE
701 */
702 public void testReplace_NullPointerException() {
703 ConcurrentHashMap c = new ConcurrentHashMap(5);
704 try {
705 c.replace(null, "whatever");
706 shouldThrow();
707 } catch (NullPointerException success) {}
708 }
709
710 /**
711 * replace(null, x, y) throws NPE
712 */
713 public void testReplaceValue_NullPointerException() {
714 ConcurrentHashMap c = new ConcurrentHashMap(5);
715 try {
716 c.replace(null, one, "whatever");
717 shouldThrow();
718 } catch (NullPointerException success) {}
719 }
720
721 /**
722 * putIfAbsent(x, null) throws NPE
723 */
724 public void testPutIfAbsent2_NullPointerException() {
725 ConcurrentHashMap c = new ConcurrentHashMap(5);
726 try {
727 c.putIfAbsent("whatever", null);
728 shouldThrow();
729 } catch (NullPointerException success) {}
730 }
731
732 /**
733 * replace(x, null) throws NPE
734 */
735 public void testReplace2_NullPointerException() {
736 ConcurrentHashMap c = new ConcurrentHashMap(5);
737 try {
738 c.replace("whatever", null);
739 shouldThrow();
740 } catch (NullPointerException success) {}
741 }
742
743 /**
744 * replace(x, null, y) throws NPE
745 */
746 public void testReplaceValue2_NullPointerException() {
747 ConcurrentHashMap c = new ConcurrentHashMap(5);
748 try {
749 c.replace("whatever", null, "A");
750 shouldThrow();
751 } catch (NullPointerException success) {}
752 }
753
754 /**
755 * replace(x, y, null) throws NPE
756 */
757 public void testReplaceValue3_NullPointerException() {
758 ConcurrentHashMap c = new ConcurrentHashMap(5);
759 try {
760 c.replace("whatever", one, null);
761 shouldThrow();
762 } catch (NullPointerException success) {}
763 }
764
765 /**
766 * remove(null) throws NPE
767 */
768 public void testRemove1_NullPointerException() {
769 ConcurrentHashMap c = new ConcurrentHashMap(5);
770 c.put("sadsdf", "asdads");
771 try {
772 c.remove(null);
773 shouldThrow();
774 } catch (NullPointerException success) {}
775 }
776
777 /**
778 * remove(null, x) throws NPE
779 */
780 public void testRemove2_NullPointerException() {
781 ConcurrentHashMap c = new ConcurrentHashMap(5);
782 c.put("sadsdf", "asdads");
783 try {
784 c.remove(null, "whatever");
785 shouldThrow();
786 } catch (NullPointerException success) {}
787 }
788
789 /**
790 * remove(x, null) returns false
791 */
792 public void testRemove3() {
793 ConcurrentHashMap c = new ConcurrentHashMap(5);
794 c.put("sadsdf", "asdads");
795 assertFalse(c.remove("sadsdf", null));
796 }
797
798 /**
799 * A deserialized/reserialized map equals original
800 */
801 public void testSerialization() throws Exception {
802 Map x = map5();
803 Map y = serialClone(x);
804
805 assertNotSame(x, y);
806 assertEquals(x.size(), y.size());
807 assertEquals(x, y);
808 assertEquals(y, x);
809 }
810
811 /**
812 * SetValue of an EntrySet entry sets value in the map.
813 */
814 public void testSetValueWriteThrough() {
815 // Adapted from a bug report by Eric Zoerner
816 ConcurrentHashMap map = new ConcurrentHashMap(2, 5.0f, 1);
817 assertTrue(map.isEmpty());
818 for (int i = 0; i < 20; i++)
819 map.put(new Integer(i), new Integer(i));
820 assertFalse(map.isEmpty());
821 Map.Entry entry1 = (Map.Entry)map.entrySet().iterator().next();
822 // Unless it happens to be first (in which case remainder of
823 // test is skipped), remove a possibly-colliding key from map
824 // which, under some implementations, may cause entry1 to be
825 // cloned in map
826 if (!entry1.getKey().equals(new Integer(16))) {
827 map.remove(new Integer(16));
828 entry1.setValue("XYZ");
829 assertTrue(map.containsValue("XYZ")); // fails if write-through broken
830 }
831 }
832
833 /**
834 * Tests performance of removeAll when the other collection is much smaller.
835 * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testRemoveAll_performance -Djsr166.expensiveTests=true tck
836 */
837 public void testRemoveAll_performance() {
838 final int mapSize = expensiveTests ? 1_000_000 : 100;
839 final int iterations = expensiveTests ? 500 : 2;
840 final ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
841 for (int i = 0; i < mapSize; i++)
842 map.put(i, i);
843 Set<Integer> keySet = map.keySet();
844 Collection<Integer> removeMe = Arrays.asList(new Integer[] { -99, -86 });
845 for (int i = 0; i < iterations; i++)
846 assertFalse(keySet.removeAll(removeMe));
847 assertEquals(mapSize, map.size());
848 }
849
850 }