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

# User Rev Content
1 dl 1.1 /*
2 jsr166 1.56 * 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 jsr166 1.23 * http://creativecommons.org/publicdomain/zero/1.0/
6 jsr166 1.14 * Other contributors include Andrew Wright, Jeffrey Hayes,
7     * Pat Fisher, Mike Judd.
8 dl 1.1 */
9    
10 jsr166 1.40 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 jsr166 1.25 import java.util.concurrent.ConcurrentHashMap;
20 dl 1.1
21 jsr166 1.40 import junit.framework.Test;
22    
23 jsr166 1.16 public class ConcurrentHashMapTest extends JSR166TestCase {
24 dl 1.1 public static void main(String[] args) {
25 jsr166 1.45 main(suite(), args);
26 dl 1.1 }
27     public static Test suite() {
28 jsr166 1.56 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 dl 1.1 }
42    
43 dl 1.5 /**
44 jsr166 1.28 * Returns a new map from Integers 1-5 to Strings "A"-"E".
45 dl 1.5 */
46 dl 1.36 private static ConcurrentHashMap<Integer, String> map5() {
47 jsr166 1.52 ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>(5);
48 dl 1.1 assertTrue(map.isEmpty());
49 jsr166 1.17 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 dl 1.1 assertFalse(map.isEmpty());
55     assertEquals(5, map.size());
56 jsr166 1.17 return map;
57 dl 1.1 }
58    
59 jsr166 1.33 /** Re-implement Integer.compare for old java versions */
60 jsr166 1.46 static int compare(int x, int y) {
61     return (x < y) ? -1 : (x > y) ? 1 : 0;
62     }
63 jsr166 1.33
64 jsr166 1.30 // 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 jsr166 1.33 return compare(value, other.value);
70 jsr166 1.30 }
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 jsr166 1.33 r = compare(size(), other.size());
104 jsr166 1.30 return r;
105     }
106     private static final long serialVersionUID = 0;
107     }
108    
109 dl 1.34 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 jsr166 1.30 /**
126     * Inserted elements that are subclasses of the same Comparable
127     * class are found.
128     */
129     public void testComparableFamily() {
130 jsr166 1.39 int size = 500; // makes measured test run time -> 60ms
131 jsr166 1.32 ConcurrentHashMap<BI, Boolean> m =
132     new ConcurrentHashMap<BI, Boolean>();
133 jsr166 1.39 for (int i = 0; i < size; i++) {
134 jsr166 1.54 assertNull(m.put(new CI(i), true));
135 jsr166 1.30 }
136 jsr166 1.39 for (int i = 0; i < size; i++) {
137 jsr166 1.30 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 jsr166 1.39 int size = 120; // makes measured test run time -> 60ms
148 jsr166 1.32 ConcurrentHashMap<Object, Boolean> m =
149     new ConcurrentHashMap<Object, Boolean>();
150 jsr166 1.39 for (int i = 0; i < size; i++) {
151 jsr166 1.30 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 jsr166 1.54 assertNull(m.putIfAbsent(bis, true));
156 jsr166 1.30 assertTrue(m.containsKey(bis));
157     if (m.putIfAbsent(bss, true) == null)
158     assertTrue(m.containsKey(bss));
159     assertTrue(m.containsKey(bis));
160     }
161 jsr166 1.39 for (int i = 0; i < size; i++) {
162     assertTrue(m.containsKey(Collections.singletonList(new BI(i))));
163 jsr166 1.30 }
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 jsr166 1.39 int size = 500; // makes measured test run time -> 60ms
173 jsr166 1.32 ConcurrentHashMap<Object, Boolean> m =
174     new ConcurrentHashMap<Object, Boolean>();
175 jsr166 1.39 for (int i = 0; i < size; i++) {
176     m.put(Collections.singletonList(new BI(i)), true);
177 jsr166 1.30 }
178    
179 jsr166 1.39 for (int i = 0; i < size; i++) {
180 jsr166 1.30 LexicographicList<BI> bis = new LexicographicList<BI>(new BI(i));
181     assertTrue(m.containsKey(bis));
182     }
183     }
184    
185 dl 1.1 /**
186 dl 1.34 * Mixtures of instances of comparable and non-comparable classes
187     * can be inserted and found.
188     */
189     public void testMixedComparable() {
190 jsr166 1.38 int size = 1200; // makes measured test run time -> 35ms
191 jsr166 1.35 ConcurrentHashMap<Object, Object> map =
192 dl 1.34 new ConcurrentHashMap<Object, Object>();
193 jsr166 1.38 Random rng = new Random();
194 jsr166 1.35 for (int i = 0; i < size; i++) {
195 dl 1.34 Object x;
196 jsr166 1.35 switch (rng.nextInt(4)) {
197 dl 1.34 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 jsr166 1.22 * clear removes all pairs
222 dl 1.1 */
223 dl 1.5 public void testClear() {
224 dl 1.1 ConcurrentHashMap map = map5();
225 jsr166 1.17 map.clear();
226 jsr166 1.26 assertEquals(0, map.size());
227 dl 1.1 }
228    
229     /**
230 jsr166 1.22 * Maps with same contents are equal
231 dl 1.5 */
232     public void testEquals() {
233     ConcurrentHashMap map1 = map5();
234     ConcurrentHashMap map2 = map5();
235     assertEquals(map1, map2);
236     assertEquals(map2, map1);
237 jsr166 1.17 map1.clear();
238 dl 1.5 assertFalse(map1.equals(map2));
239     assertFalse(map2.equals(map1));
240     }
241    
242 dl 1.36 /**
243 jsr166 1.37 * hashCode() equals sum of each key.hashCode ^ value.hashCode
244     */
245 dl 1.36 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 dl 1.5 /**
254 jsr166 1.22 * contains returns true for contained value
255 dl 1.1 */
256 dl 1.5 public void testContains() {
257 dl 1.1 ConcurrentHashMap map = map5();
258 jsr166 1.17 assertTrue(map.contains("A"));
259 dl 1.1 assertFalse(map.contains("Z"));
260     }
261 jsr166 1.14
262 dl 1.1 /**
263 jsr166 1.22 * containsKey returns true for contained key
264 dl 1.1 */
265 dl 1.5 public void testContainsKey() {
266 dl 1.1 ConcurrentHashMap map = map5();
267 jsr166 1.17 assertTrue(map.containsKey(one));
268 dl 1.5 assertFalse(map.containsKey(zero));
269 dl 1.1 }
270    
271     /**
272 jsr166 1.22 * containsValue returns true for held values
273 dl 1.1 */
274 dl 1.5 public void testContainsValue() {
275 dl 1.1 ConcurrentHashMap map = map5();
276 jsr166 1.17 assertTrue(map.containsValue("A"));
277 dl 1.11 assertFalse(map.containsValue("Z"));
278 dl 1.1 }
279    
280     /**
281 jsr166 1.22 * enumeration returns an enumeration containing the correct
282     * elements
283 dl 1.1 */
284 dl 1.5 public void testEnumeration() {
285 dl 1.1 ConcurrentHashMap map = map5();
286 jsr166 1.17 Enumeration e = map.elements();
287     int count = 0;
288     while (e.hasMoreElements()) {
289     count++;
290     e.nextElement();
291     }
292     assertEquals(5, count);
293 dl 1.4 }
294    
295     /**
296 jsr166 1.22 * get returns the correct element at the given key,
297     * or null if not present
298 dl 1.1 */
299 dl 1.5 public void testGet() {
300 dl 1.1 ConcurrentHashMap map = map5();
301 jsr166 1.17 assertEquals("A", (String)map.get(one));
302 dl 1.1 ConcurrentHashMap empty = new ConcurrentHashMap();
303 dl 1.5 assertNull(map.get("anything"));
304 jsr166 1.42 assertNull(empty.get("anything"));
305 dl 1.1 }
306    
307     /**
308 jsr166 1.22 * isEmpty is true of empty map and false for non-empty
309 dl 1.1 */
310 dl 1.5 public void testIsEmpty() {
311 dl 1.1 ConcurrentHashMap empty = new ConcurrentHashMap();
312     ConcurrentHashMap map = map5();
313 jsr166 1.17 assertTrue(empty.isEmpty());
314 dl 1.1 assertFalse(map.isEmpty());
315     }
316    
317     /**
318 jsr166 1.22 * keys returns an enumeration containing all the keys from the map
319 dl 1.1 */
320 dl 1.5 public void testKeys() {
321 dl 1.1 ConcurrentHashMap map = map5();
322 jsr166 1.17 Enumeration e = map.keys();
323     int count = 0;
324     while (e.hasMoreElements()) {
325     count++;
326     e.nextElement();
327     }
328     assertEquals(5, count);
329 dl 1.1 }
330    
331     /**
332 jsr166 1.22 * keySet returns a Set containing all the keys
333 dl 1.1 */
334 dl 1.5 public void testKeySet() {
335 dl 1.1 ConcurrentHashMap map = map5();
336 jsr166 1.17 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 dl 1.1 }
344    
345 dl 1.5 /**
346 jsr166 1.50 * 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 jsr166 1.22 * keySet.toArray returns contains all keys
362 dl 1.13 */
363     public void testKeySetToArray() {
364     ConcurrentHashMap map = map5();
365 jsr166 1.17 Set s = map.keySet();
366 dl 1.13 Object[] ar = s.toArray();
367     assertTrue(s.containsAll(Arrays.asList(ar)));
368 jsr166 1.17 assertEquals(5, ar.length);
369 dl 1.13 ar[0] = m10;
370     assertFalse(s.containsAll(Arrays.asList(ar)));
371     }
372    
373     /**
374 jsr166 1.22 * Values.toArray contains all values
375 dl 1.13 */
376     public void testValuesToArray() {
377     ConcurrentHashMap map = map5();
378 jsr166 1.17 Collection v = map.values();
379 dl 1.13 Object[] ar = v.toArray();
380     ArrayList s = new ArrayList(Arrays.asList(ar));
381 jsr166 1.17 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 dl 1.13 }
388    
389     /**
390 jsr166 1.22 * entrySet.toArray contains all entries
391 dl 1.13 */
392     public void testEntrySetToArray() {
393     ConcurrentHashMap map = map5();
394 jsr166 1.17 Set s = map.entrySet();
395 dl 1.13 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 dl 1.5 * values collection contains all values
405     */
406     public void testValues() {
407 dl 1.1 ConcurrentHashMap map = map5();
408 jsr166 1.17 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 dl 1.1 }
416    
417 dl 1.5 /**
418     * entrySet contains all pairs
419     */
420     public void testEntrySet() {
421 dl 1.1 ConcurrentHashMap map = map5();
422 jsr166 1.17 Set s = map.entrySet();
423     assertEquals(5, s.size());
424 dl 1.1 Iterator it = s.iterator();
425     while (it.hasNext()) {
426     Map.Entry e = (Map.Entry) it.next();
427 jsr166 1.14 assertTrue(
428 dl 1.1 (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 jsr166 1.22 * putAll adds all key-value pairs from the given map
438 dl 1.1 */
439 dl 1.5 public void testPutAll() {
440 dl 1.1 ConcurrentHashMap empty = new ConcurrentHashMap();
441     ConcurrentHashMap map = map5();
442 jsr166 1.17 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 dl 1.1 }
450    
451     /**
452 jsr166 1.22 * putIfAbsent works when the given key is not present
453 dl 1.1 */
454 dl 1.5 public void testPutIfAbsent() {
455 dl 1.1 ConcurrentHashMap map = map5();
456 jsr166 1.17 map.putIfAbsent(six, "Z");
457 dl 1.7 assertTrue(map.containsKey(six));
458 dl 1.1 }
459    
460     /**
461 jsr166 1.22 * putIfAbsent does not add the pair if the key is already present
462 dl 1.1 */
463 dl 1.5 public void testPutIfAbsent2() {
464 dl 1.1 ConcurrentHashMap map = map5();
465     assertEquals("A", map.putIfAbsent(one, "Z"));
466     }
467    
468     /**
469 jsr166 1.22 * replace fails when the given key is not present
470 dl 1.7 */
471     public void testReplace() {
472     ConcurrentHashMap map = map5();
473 jsr166 1.17 assertNull(map.replace(six, "Z"));
474 dl 1.7 assertFalse(map.containsKey(six));
475     }
476    
477     /**
478 jsr166 1.22 * replace succeeds if the key is already present
479 dl 1.7 */
480     public void testReplace2() {
481     ConcurrentHashMap map = map5();
482 dl 1.8 assertNotNull(map.replace(one, "Z"));
483 dl 1.7 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 jsr166 1.17 assertFalse(map.replace(one, "Z", "Z"));
493 dl 1.7 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 jsr166 1.17 assertTrue(map.replace(one, "A", "Z"));
503 dl 1.7 assertEquals("Z", map.get(one));
504     }
505    
506     /**
507 jsr166 1.22 * remove removes the correct key-value pair from the map
508 dl 1.1 */
509 dl 1.5 public void testRemove() {
510 dl 1.1 ConcurrentHashMap map = map5();
511 jsr166 1.17 map.remove(five);
512     assertEquals(4, map.size());
513     assertFalse(map.containsKey(five));
514 dl 1.1 }
515    
516 dl 1.5 /**
517     * remove(key,value) removes only if pair present
518     */
519     public void testRemove2() {
520 dl 1.1 ConcurrentHashMap map = map5();
521 jsr166 1.17 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 dl 1.1 }
528    
529     /**
530 jsr166 1.22 * size returns the correct values
531 dl 1.1 */
532 dl 1.5 public void testSize() {
533 dl 1.1 ConcurrentHashMap map = map5();
534     ConcurrentHashMap empty = new ConcurrentHashMap();
535 jsr166 1.17 assertEquals(0, empty.size());
536     assertEquals(5, map.size());
537 dl 1.1 }
538    
539 dl 1.5 /**
540     * toString contains toString of elements
541     */
542     public void testToString() {
543 dl 1.1 ConcurrentHashMap map = map5();
544     String s = map.toString();
545     for (int i = 1; i <= 5; ++i) {
546 jsr166 1.24 assertTrue(s.contains(String.valueOf(i)));
547 dl 1.1 }
548 jsr166 1.14 }
549 dl 1.1
550     // Exception tests
551 jsr166 1.14
552 dl 1.5 /**
553 dl 1.36 * Cannot create with only negative capacity
554 dl 1.5 */
555     public void testConstructor1() {
556     try {
557 dl 1.36 new ConcurrentHashMap(-1);
558 dl 1.5 shouldThrow();
559 jsr166 1.19 } catch (IllegalArgumentException success) {}
560 dl 1.1 }
561    
562 dl 1.5 /**
563 dl 1.36 * Constructor (initialCapacity, loadFactor) throws
564     * IllegalArgumentException if either argument is negative
565 jsr166 1.47 */
566 dl 1.5 public void testConstructor2() {
567     try {
568 dl 1.36 new ConcurrentHashMap(-1, .75f);
569 dl 1.5 shouldThrow();
570 jsr166 1.43 } catch (IllegalArgumentException success) {}
571 jsr166 1.37
572 dl 1.36 try {
573     new ConcurrentHashMap(16, -1);
574     shouldThrow();
575 jsr166 1.43 } catch (IllegalArgumentException success) {}
576 dl 1.1 }
577 jsr166 1.37
578     /**
579     * Constructor (initialCapacity, loadFactor, concurrencyLevel)
580     * throws IllegalArgumentException if any argument is negative
581     */
582 dl 1.36 public void testConstructor3() {
583 jsr166 1.37 try {
584     new ConcurrentHashMap(-1, .75f, 1);
585     shouldThrow();
586 jsr166 1.43 } catch (IllegalArgumentException success) {}
587 jsr166 1.37
588     try {
589     new ConcurrentHashMap(16, -1, 1);
590     shouldThrow();
591 jsr166 1.43 } catch (IllegalArgumentException success) {}
592 jsr166 1.37
593     try {
594     new ConcurrentHashMap(16, .75f, -1);
595     shouldThrow();
596 jsr166 1.43 } catch (IllegalArgumentException success) {}
597 jsr166 1.37 }
598 dl 1.1
599 dl 1.5 /**
600 dl 1.36 * ConcurrentHashMap(map) throws NullPointerException if the given
601     * map is null
602 dl 1.5 */
603 dl 1.36 public void testConstructor4() {
604 dl 1.5 try {
605 dl 1.36 new ConcurrentHashMap(null);
606 dl 1.5 shouldThrow();
607 jsr166 1.43 } catch (NullPointerException success) {}
608 dl 1.36 }
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 dl 1.1 }
621    
622 dl 1.5 /**
623     * get(null) throws NPE
624     */
625     public void testGet_NullPointerException() {
626 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
627 dl 1.5 try {
628 dl 1.1 c.get(null);
629 dl 1.5 shouldThrow();
630 jsr166 1.19 } catch (NullPointerException success) {}
631 dl 1.1 }
632    
633 dl 1.5 /**
634     * containsKey(null) throws NPE
635     */
636     public void testContainsKey_NullPointerException() {
637 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
638 dl 1.5 try {
639 dl 1.1 c.containsKey(null);
640 dl 1.5 shouldThrow();
641 jsr166 1.19 } catch (NullPointerException success) {}
642 dl 1.1 }
643    
644 dl 1.5 /**
645     * containsValue(null) throws NPE
646     */
647     public void testContainsValue_NullPointerException() {
648 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
649 dl 1.5 try {
650 dl 1.1 c.containsValue(null);
651 dl 1.5 shouldThrow();
652 jsr166 1.19 } catch (NullPointerException success) {}
653 dl 1.1 }
654    
655 dl 1.5 /**
656     * contains(null) throws NPE
657     */
658     public void testContains_NullPointerException() {
659 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
660 dl 1.5 try {
661 dl 1.1 c.contains(null);
662 dl 1.5 shouldThrow();
663 jsr166 1.19 } catch (NullPointerException success) {}
664 dl 1.1 }
665    
666 dl 1.5 /**
667     * put(null,x) throws NPE
668     */
669     public void testPut1_NullPointerException() {
670 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
671 dl 1.5 try {
672 dl 1.1 c.put(null, "whatever");
673 dl 1.5 shouldThrow();
674 jsr166 1.19 } catch (NullPointerException success) {}
675 dl 1.1 }
676    
677 dl 1.5 /**
678     * put(x, null) throws NPE
679     */
680     public void testPut2_NullPointerException() {
681 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
682 dl 1.5 try {
683 dl 1.1 c.put("whatever", null);
684 dl 1.5 shouldThrow();
685 jsr166 1.19 } catch (NullPointerException success) {}
686 dl 1.1 }
687    
688 dl 1.5 /**
689     * putIfAbsent(null, x) throws NPE
690     */
691     public void testPutIfAbsent1_NullPointerException() {
692 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
693 dl 1.5 try {
694 dl 1.1 c.putIfAbsent(null, "whatever");
695 dl 1.5 shouldThrow();
696 jsr166 1.19 } catch (NullPointerException success) {}
697 dl 1.1 }
698    
699 dl 1.5 /**
700 dl 1.7 * replace(null, x) throws NPE
701     */
702     public void testReplace_NullPointerException() {
703 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
704 dl 1.7 try {
705     c.replace(null, "whatever");
706     shouldThrow();
707 jsr166 1.19 } catch (NullPointerException success) {}
708 dl 1.7 }
709    
710     /**
711     * replace(null, x, y) throws NPE
712     */
713     public void testReplaceValue_NullPointerException() {
714 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
715 dl 1.7 try {
716     c.replace(null, one, "whatever");
717     shouldThrow();
718 jsr166 1.19 } catch (NullPointerException success) {}
719 dl 1.7 }
720    
721     /**
722 dl 1.5 * putIfAbsent(x, null) throws NPE
723     */
724     public void testPutIfAbsent2_NullPointerException() {
725 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
726 dl 1.5 try {
727 dl 1.1 c.putIfAbsent("whatever", null);
728 dl 1.7 shouldThrow();
729 jsr166 1.19 } catch (NullPointerException success) {}
730 dl 1.7 }
731    
732     /**
733     * replace(x, null) throws NPE
734     */
735     public void testReplace2_NullPointerException() {
736 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
737 dl 1.7 try {
738     c.replace("whatever", null);
739     shouldThrow();
740 jsr166 1.19 } catch (NullPointerException success) {}
741 dl 1.7 }
742    
743     /**
744     * replace(x, null, y) throws NPE
745     */
746     public void testReplaceValue2_NullPointerException() {
747 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
748 dl 1.7 try {
749     c.replace("whatever", null, "A");
750     shouldThrow();
751 jsr166 1.19 } catch (NullPointerException success) {}
752 dl 1.7 }
753    
754     /**
755     * replace(x, y, null) throws NPE
756     */
757     public void testReplaceValue3_NullPointerException() {
758 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
759 dl 1.7 try {
760     c.replace("whatever", one, null);
761 dl 1.5 shouldThrow();
762 jsr166 1.19 } catch (NullPointerException success) {}
763 dl 1.1 }
764    
765 dl 1.5 /**
766     * remove(null) throws NPE
767     */
768     public void testRemove1_NullPointerException() {
769 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
770     c.put("sadsdf", "asdads");
771 dl 1.5 try {
772 dl 1.1 c.remove(null);
773 dl 1.5 shouldThrow();
774 jsr166 1.19 } catch (NullPointerException success) {}
775 dl 1.1 }
776    
777 dl 1.5 /**
778     * remove(null, x) throws NPE
779     */
780     public void testRemove2_NullPointerException() {
781 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
782     c.put("sadsdf", "asdads");
783 dl 1.5 try {
784 dl 1.1 c.remove(null, "whatever");
785 dl 1.5 shouldThrow();
786 jsr166 1.19 } catch (NullPointerException success) {}
787 dl 1.1 }
788 dl 1.2
789 dl 1.5 /**
790 dl 1.12 * remove(x, null) returns false
791     */
792     public void testRemove3() {
793 jsr166 1.19 ConcurrentHashMap c = new ConcurrentHashMap(5);
794     c.put("sadsdf", "asdads");
795     assertFalse(c.remove("sadsdf", null));
796 dl 1.12 }
797    
798     /**
799 jsr166 1.55 * A deserialized/reserialized map equals original
800 dl 1.5 */
801 jsr166 1.18 public void testSerialization() throws Exception {
802 jsr166 1.25 Map x = map5();
803     Map y = serialClone(x);
804 dl 1.2
805 jsr166 1.31 assertNotSame(x, y);
806 jsr166 1.25 assertEquals(x.size(), y.size());
807     assertEquals(x, y);
808     assertEquals(y, x);
809 dl 1.2 }
810 dl 1.6
811     /**
812     * SetValue of an EntrySet entry sets value in the map.
813     */
814     public void testSetValueWriteThrough() {
815 jsr166 1.14 // Adapted from a bug report by Eric Zoerner
816 dl 1.6 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 dl 1.29 // 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 dl 1.6 }
832 jsr166 1.14
833 jsr166 1.48 /**
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 jsr166 1.49 final int mapSize = expensiveTests ? 1_000_000 : 100;
839     final int iterations = expensiveTests ? 500 : 2;
840     final ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
841 jsr166 1.48 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 jsr166 1.49
850 dl 1.1 }