ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/TreeMapTest.java
Revision: 1.35
Committed: Sun Sep 29 20:40:48 2019 UTC (4 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.34: +0 -2 lines
Log Message:
add MapTest.testConcurrentAccess

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.18 * http://creativecommons.org/publicdomain/zero/1.0/
5 dl 1.1 */
6    
7 jsr166 1.28 import java.util.Arrays;
8     import java.util.BitSet;
9     import java.util.Collection;
10     import java.util.Iterator;
11     import java.util.Map;
12     import java.util.NavigableMap;
13     import java.util.NavigableSet;
14     import java.util.NoSuchElementException;
15     import java.util.Random;
16     import java.util.Set;
17     import java.util.TreeMap;
18    
19     import junit.framework.Test;
20 dl 1.1
21     public class TreeMapTest extends JSR166TestCase {
22     public static void main(String[] args) {
23 jsr166 1.31 main(suite(), args);
24 dl 1.1 }
25     public static Test suite() {
26 jsr166 1.34 class Implementation implements MapImplementation {
27     public Class<?> klazz() { return TreeMap.class; }
28     public Map emptyMap() { return new TreeMap(); }
29     public boolean isConcurrent() { return false; }
30     public boolean permitsNullKeys() { return false; }
31     public boolean permitsNullValues() { return true; }
32     public boolean supportsSetValue() { return true; }
33     }
34     return newTestSuite(
35     TreeMapTest.class,
36     MapTest.testSuite(new Implementation()));
37 dl 1.1 }
38    
39     /**
40 jsr166 1.25 * Returns a new map from Integers 1-5 to Strings "A"-"E".
41 dl 1.1 */
42 jsr166 1.6 private static TreeMap map5() {
43 jsr166 1.9 TreeMap map = new TreeMap();
44 dl 1.1 assertTrue(map.isEmpty());
45 jsr166 1.9 map.put(one, "A");
46     map.put(five, "E");
47     map.put(three, "C");
48     map.put(two, "B");
49     map.put(four, "D");
50 dl 1.1 assertFalse(map.isEmpty());
51     assertEquals(5, map.size());
52 jsr166 1.9 return map;
53 dl 1.1 }
54    
55     /**
56 jsr166 1.16 * clear removes all pairs
57 dl 1.1 */
58     public void testClear() {
59     TreeMap map = map5();
60 jsr166 1.9 map.clear();
61 jsr166 1.22 assertEquals(0, map.size());
62 dl 1.1 }
63    
64     /**
65 jsr166 1.26 * copy constructor creates map equal to source map
66 dl 1.1 */
67     public void testConstructFromSorted() {
68     TreeMap map = map5();
69     TreeMap map2 = new TreeMap(map);
70     assertEquals(map, map2);
71     }
72    
73     /**
74 jsr166 1.16 * Maps with same contents are equal
75 dl 1.1 */
76     public void testEquals() {
77     TreeMap map1 = map5();
78     TreeMap map2 = map5();
79     assertEquals(map1, map2);
80     assertEquals(map2, map1);
81 jsr166 1.9 map1.clear();
82 dl 1.1 assertFalse(map1.equals(map2));
83     assertFalse(map2.equals(map1));
84     }
85    
86     /**
87 jsr166 1.16 * containsKey returns true for contained key
88 dl 1.1 */
89     public void testContainsKey() {
90     TreeMap map = map5();
91 jsr166 1.9 assertTrue(map.containsKey(one));
92 dl 1.1 assertFalse(map.containsKey(zero));
93     }
94    
95     /**
96 jsr166 1.16 * containsValue returns true for held values
97 dl 1.1 */
98     public void testContainsValue() {
99     TreeMap map = map5();
100 jsr166 1.9 assertTrue(map.containsValue("A"));
101 dl 1.1 assertFalse(map.containsValue("Z"));
102     }
103    
104     /**
105 jsr166 1.16 * get returns the correct element at the given key,
106     * or null if not present
107 dl 1.1 */
108     public void testGet() {
109     TreeMap map = map5();
110 jsr166 1.9 assertEquals("A", (String)map.get(one));
111 dl 1.1 TreeMap empty = new TreeMap();
112     assertNull(empty.get(one));
113     }
114    
115     /**
116 jsr166 1.16 * isEmpty is true of empty map and false for non-empty
117 dl 1.1 */
118     public void testIsEmpty() {
119     TreeMap empty = new TreeMap();
120     TreeMap map = map5();
121 jsr166 1.9 assertTrue(empty.isEmpty());
122 dl 1.1 assertFalse(map.isEmpty());
123     }
124    
125     /**
126 jsr166 1.16 * firstKey returns first key
127 dl 1.1 */
128     public void testFirstKey() {
129     TreeMap map = map5();
130 jsr166 1.9 assertEquals(one, map.firstKey());
131 dl 1.1 }
132    
133     /**
134 jsr166 1.16 * lastKey returns last key
135 dl 1.1 */
136     public void testLastKey() {
137     TreeMap map = map5();
138 jsr166 1.9 assertEquals(five, map.lastKey());
139 dl 1.1 }
140    
141     /**
142 jsr166 1.16 * keySet.toArray returns contains all keys
143 dl 1.1 */
144     public void testKeySetToArray() {
145     TreeMap map = map5();
146 jsr166 1.9 Set s = map.keySet();
147 dl 1.1 Object[] ar = s.toArray();
148     assertTrue(s.containsAll(Arrays.asList(ar)));
149 jsr166 1.9 assertEquals(5, ar.length);
150 dl 1.1 ar[0] = m10;
151     assertFalse(s.containsAll(Arrays.asList(ar)));
152     }
153    
154     /**
155 jsr166 1.16 * descendingkeySet.toArray returns contains all keys
156 dl 1.1 */
157     public void testDescendingKeySetToArray() {
158     TreeMap map = map5();
159 jsr166 1.9 Set s = map.descendingKeySet();
160 dl 1.1 Object[] ar = s.toArray();
161 jsr166 1.9 assertEquals(5, ar.length);
162 dl 1.1 assertTrue(s.containsAll(Arrays.asList(ar)));
163     ar[0] = m10;
164     assertFalse(s.containsAll(Arrays.asList(ar)));
165     }
166    
167     /**
168 jsr166 1.16 * keySet returns a Set containing all the keys
169 dl 1.1 */
170     public void testKeySet() {
171     TreeMap map = map5();
172 jsr166 1.9 Set s = map.keySet();
173     assertEquals(5, s.size());
174     assertTrue(s.contains(one));
175     assertTrue(s.contains(two));
176     assertTrue(s.contains(three));
177     assertTrue(s.contains(four));
178     assertTrue(s.contains(five));
179 dl 1.1 }
180    
181     /**
182 jsr166 1.16 * keySet is ordered
183 dl 1.1 */
184     public void testKeySetOrder() {
185     TreeMap map = map5();
186 jsr166 1.9 Set s = map.keySet();
187 dl 1.1 Iterator i = s.iterator();
188     Integer last = (Integer)i.next();
189     assertEquals(last, one);
190 dl 1.5 int count = 1;
191 dl 1.1 while (i.hasNext()) {
192     Integer k = (Integer)i.next();
193     assertTrue(last.compareTo(k) < 0);
194     last = k;
195 dl 1.5 ++count;
196 dl 1.1 }
197 jsr166 1.22 assertEquals(5, count);
198 dl 1.5 }
199    
200     /**
201     * descending iterator of key set is inverse ordered
202     */
203     public void testKeySetDescendingIteratorOrder() {
204     TreeMap map = map5();
205 jsr166 1.9 NavigableSet s = map.navigableKeySet();
206 dl 1.5 Iterator i = s.descendingIterator();
207     Integer last = (Integer)i.next();
208     assertEquals(last, five);
209     int count = 1;
210     while (i.hasNext()) {
211     Integer k = (Integer)i.next();
212     assertTrue(last.compareTo(k) > 0);
213     last = k;
214     ++count;
215     }
216 jsr166 1.22 assertEquals(5, count);
217 dl 1.1 }
218    
219     /**
220 jsr166 1.16 * descendingKeySet is ordered
221 dl 1.1 */
222     public void testDescendingKeySetOrder() {
223     TreeMap map = map5();
224 jsr166 1.9 Set s = map.descendingKeySet();
225 dl 1.1 Iterator i = s.iterator();
226     Integer last = (Integer)i.next();
227     assertEquals(last, five);
228 dl 1.5 int count = 1;
229 dl 1.1 while (i.hasNext()) {
230     Integer k = (Integer)i.next();
231     assertTrue(last.compareTo(k) > 0);
232     last = k;
233 dl 1.5 ++count;
234     }
235 jsr166 1.22 assertEquals(5, count);
236 dl 1.5 }
237    
238     /**
239 jsr166 1.16 * descending iterator of descendingKeySet is ordered
240 dl 1.5 */
241     public void testDescendingKeySetDescendingIteratorOrder() {
242     TreeMap map = map5();
243 jsr166 1.9 NavigableSet s = map.descendingKeySet();
244 dl 1.5 Iterator i = s.descendingIterator();
245     Integer last = (Integer)i.next();
246     assertEquals(last, one);
247     int count = 1;
248     while (i.hasNext()) {
249     Integer k = (Integer)i.next();
250     assertTrue(last.compareTo(k) < 0);
251     last = k;
252     ++count;
253 dl 1.1 }
254 jsr166 1.22 assertEquals(5, count);
255 dl 1.1 }
256    
257     /**
258     * values collection contains all values
259     */
260     public void testValues() {
261     TreeMap map = map5();
262 jsr166 1.9 Collection s = map.values();
263     assertEquals(5, s.size());
264     assertTrue(s.contains("A"));
265     assertTrue(s.contains("B"));
266     assertTrue(s.contains("C"));
267     assertTrue(s.contains("D"));
268     assertTrue(s.contains("E"));
269 dl 1.1 }
270    
271     /**
272     * entrySet contains all pairs
273     */
274     public void testEntrySet() {
275     TreeMap map = map5();
276 jsr166 1.9 Set s = map.entrySet();
277     assertEquals(5, s.size());
278 dl 1.1 Iterator it = s.iterator();
279     while (it.hasNext()) {
280     Map.Entry e = (Map.Entry) it.next();
281 jsr166 1.6 assertTrue(
282 dl 1.1 (e.getKey().equals(one) && e.getValue().equals("A")) ||
283     (e.getKey().equals(two) && e.getValue().equals("B")) ||
284     (e.getKey().equals(three) && e.getValue().equals("C")) ||
285     (e.getKey().equals(four) && e.getValue().equals("D")) ||
286     (e.getKey().equals(five) && e.getValue().equals("E")));
287     }
288     }
289    
290     /**
291     * descendingEntrySet contains all pairs
292     */
293     public void testDescendingEntrySet() {
294     TreeMap map = map5();
295 jsr166 1.9 Set s = map.descendingMap().entrySet();
296     assertEquals(5, s.size());
297 dl 1.1 Iterator it = s.iterator();
298     while (it.hasNext()) {
299     Map.Entry e = (Map.Entry) it.next();
300 jsr166 1.6 assertTrue(
301 dl 1.1 (e.getKey().equals(one) && e.getValue().equals("A")) ||
302     (e.getKey().equals(two) && e.getValue().equals("B")) ||
303     (e.getKey().equals(three) && e.getValue().equals("C")) ||
304     (e.getKey().equals(four) && e.getValue().equals("D")) ||
305     (e.getKey().equals(five) && e.getValue().equals("E")));
306     }
307     }
308    
309     /**
310 jsr166 1.16 * entrySet.toArray contains all entries
311 dl 1.1 */
312     public void testEntrySetToArray() {
313     TreeMap map = map5();
314 jsr166 1.9 Set s = map.entrySet();
315 dl 1.1 Object[] ar = s.toArray();
316     assertEquals(5, ar.length);
317     for (int i = 0; i < 5; ++i) {
318     assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
319     assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
320     }
321     }
322    
323     /**
324 jsr166 1.16 * descendingEntrySet.toArray contains all entries
325 dl 1.1 */
326     public void testDescendingEntrySetToArray() {
327     TreeMap map = map5();
328 jsr166 1.9 Set s = map.descendingMap().entrySet();
329 dl 1.1 Object[] ar = s.toArray();
330     assertEquals(5, ar.length);
331     for (int i = 0; i < 5; ++i) {
332     assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
333     assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
334     }
335     }
336    
337     /**
338 jsr166 1.16 * putAll adds all key-value pairs from the given map
339 dl 1.1 */
340     public void testPutAll() {
341     TreeMap empty = new TreeMap();
342     TreeMap map = map5();
343 jsr166 1.9 empty.putAll(map);
344     assertEquals(5, empty.size());
345     assertTrue(empty.containsKey(one));
346     assertTrue(empty.containsKey(two));
347     assertTrue(empty.containsKey(three));
348     assertTrue(empty.containsKey(four));
349     assertTrue(empty.containsKey(five));
350 dl 1.1 }
351    
352     /**
353 jsr166 1.16 * remove removes the correct key-value pair from the map
354 dl 1.1 */
355     public void testRemove() {
356     TreeMap map = map5();
357 jsr166 1.9 map.remove(five);
358     assertEquals(4, map.size());
359     assertFalse(map.containsKey(five));
360 dl 1.1 }
361    
362     /**
363     * lowerEntry returns preceding entry.
364     */
365     public void testLowerEntry() {
366     TreeMap map = map5();
367     Map.Entry e1 = map.lowerEntry(three);
368     assertEquals(two, e1.getKey());
369    
370     Map.Entry e2 = map.lowerEntry(six);
371     assertEquals(five, e2.getKey());
372    
373     Map.Entry e3 = map.lowerEntry(one);
374     assertNull(e3);
375    
376     Map.Entry e4 = map.lowerEntry(zero);
377     assertNull(e4);
378     }
379    
380     /**
381     * higherEntry returns next entry.
382     */
383     public void testHigherEntry() {
384     TreeMap map = map5();
385     Map.Entry e1 = map.higherEntry(three);
386     assertEquals(four, e1.getKey());
387    
388     Map.Entry e2 = map.higherEntry(zero);
389     assertEquals(one, e2.getKey());
390    
391     Map.Entry e3 = map.higherEntry(five);
392     assertNull(e3);
393    
394     Map.Entry e4 = map.higherEntry(six);
395     assertNull(e4);
396     }
397    
398     /**
399     * floorEntry returns preceding entry.
400     */
401     public void testFloorEntry() {
402     TreeMap map = map5();
403     Map.Entry e1 = map.floorEntry(three);
404     assertEquals(three, e1.getKey());
405    
406     Map.Entry e2 = map.floorEntry(six);
407     assertEquals(five, e2.getKey());
408    
409     Map.Entry e3 = map.floorEntry(one);
410     assertEquals(one, e3.getKey());
411    
412     Map.Entry e4 = map.floorEntry(zero);
413     assertNull(e4);
414     }
415    
416     /**
417     * ceilingEntry returns next entry.
418     */
419     public void testCeilingEntry() {
420     TreeMap map = map5();
421     Map.Entry e1 = map.ceilingEntry(three);
422     assertEquals(three, e1.getKey());
423    
424     Map.Entry e2 = map.ceilingEntry(zero);
425     assertEquals(one, e2.getKey());
426    
427     Map.Entry e3 = map.ceilingEntry(five);
428     assertEquals(five, e3.getKey());
429    
430     Map.Entry e4 = map.ceilingEntry(six);
431     assertNull(e4);
432     }
433    
434     /**
435     * lowerKey returns preceding element
436     */
437     public void testLowerKey() {
438     TreeMap q = map5();
439     Object e1 = q.lowerKey(three);
440     assertEquals(two, e1);
441    
442     Object e2 = q.lowerKey(six);
443     assertEquals(five, e2);
444    
445     Object e3 = q.lowerKey(one);
446     assertNull(e3);
447    
448     Object e4 = q.lowerKey(zero);
449     assertNull(e4);
450     }
451    
452     /**
453     * higherKey returns next element
454     */
455     public void testHigherKey() {
456     TreeMap q = map5();
457     Object e1 = q.higherKey(three);
458     assertEquals(four, e1);
459    
460     Object e2 = q.higherKey(zero);
461     assertEquals(one, e2);
462    
463     Object e3 = q.higherKey(five);
464     assertNull(e3);
465    
466     Object e4 = q.higherKey(six);
467     assertNull(e4);
468     }
469    
470     /**
471     * floorKey returns preceding element
472     */
473     public void testFloorKey() {
474     TreeMap q = map5();
475     Object e1 = q.floorKey(three);
476     assertEquals(three, e1);
477    
478     Object e2 = q.floorKey(six);
479     assertEquals(five, e2);
480    
481     Object e3 = q.floorKey(one);
482     assertEquals(one, e3);
483    
484     Object e4 = q.floorKey(zero);
485     assertNull(e4);
486     }
487    
488     /**
489     * ceilingKey returns next element
490     */
491     public void testCeilingKey() {
492     TreeMap q = map5();
493     Object e1 = q.ceilingKey(three);
494     assertEquals(three, e1);
495    
496     Object e2 = q.ceilingKey(zero);
497     assertEquals(one, e2);
498    
499     Object e3 = q.ceilingKey(five);
500     assertEquals(five, e3);
501    
502     Object e4 = q.ceilingKey(six);
503     assertNull(e4);
504     }
505    
506     /**
507     * pollFirstEntry returns entries in order
508     */
509     public void testPollFirstEntry() {
510     TreeMap map = map5();
511     Map.Entry e = map.pollFirstEntry();
512     assertEquals(one, e.getKey());
513     assertEquals("A", e.getValue());
514     e = map.pollFirstEntry();
515     assertEquals(two, e.getKey());
516     map.put(one, "A");
517     e = map.pollFirstEntry();
518     assertEquals(one, e.getKey());
519     assertEquals("A", e.getValue());
520     e = map.pollFirstEntry();
521     assertEquals(three, e.getKey());
522     map.remove(four);
523     e = map.pollFirstEntry();
524     assertEquals(five, e.getKey());
525     try {
526     e.setValue("A");
527     shouldThrow();
528 jsr166 1.11 } catch (UnsupportedOperationException success) {}
529 dl 1.1 e = map.pollFirstEntry();
530     assertNull(e);
531     }
532    
533     /**
534     * pollLastEntry returns entries in order
535     */
536     public void testPollLastEntry() {
537     TreeMap map = map5();
538     Map.Entry e = map.pollLastEntry();
539     assertEquals(five, e.getKey());
540     assertEquals("E", e.getValue());
541     e = map.pollLastEntry();
542     assertEquals(four, e.getKey());
543     map.put(five, "E");
544     e = map.pollLastEntry();
545     assertEquals(five, e.getKey());
546     assertEquals("E", e.getValue());
547     e = map.pollLastEntry();
548     assertEquals(three, e.getKey());
549     map.remove(two);
550     e = map.pollLastEntry();
551     assertEquals(one, e.getKey());
552     try {
553     e.setValue("E");
554     shouldThrow();
555 jsr166 1.11 } catch (UnsupportedOperationException success) {}
556 dl 1.1 e = map.pollLastEntry();
557     assertNull(e);
558     }
559    
560     /**
561 jsr166 1.16 * size returns the correct values
562 dl 1.1 */
563     public void testSize() {
564     TreeMap map = map5();
565     TreeMap empty = new TreeMap();
566 jsr166 1.9 assertEquals(0, empty.size());
567     assertEquals(5, map.size());
568 dl 1.1 }
569    
570     /**
571     * toString contains toString of elements
572     */
573     public void testToString() {
574     TreeMap map = map5();
575     String s = map.toString();
576     for (int i = 1; i <= 5; ++i) {
577 jsr166 1.20 assertTrue(s.contains(String.valueOf(i)));
578 dl 1.1 }
579 jsr166 1.6 }
580 dl 1.1
581     // Exception tests
582    
583     /**
584     * get(null) of nonempty map throws NPE
585     */
586     public void testGet_NullPointerException() {
587 jsr166 1.30 TreeMap c = map5();
588 dl 1.1 try {
589     c.get(null);
590     shouldThrow();
591 jsr166 1.11 } catch (NullPointerException success) {}
592 dl 1.1 }
593    
594     /**
595     * containsKey(null) of nonempty map throws NPE
596     */
597     public void testContainsKey_NullPointerException() {
598 jsr166 1.30 TreeMap c = map5();
599 dl 1.1 try {
600     c.containsKey(null);
601     shouldThrow();
602 jsr166 1.11 } catch (NullPointerException success) {}
603 dl 1.1 }
604    
605     /**
606     * remove(null) throws NPE for nonempty map
607     */
608     public void testRemove1_NullPointerException() {
609 jsr166 1.30 TreeMap c = new TreeMap();
610     c.put("sadsdf", "asdads");
611 dl 1.1 try {
612     c.remove(null);
613     shouldThrow();
614 jsr166 1.11 } catch (NullPointerException success) {}
615 dl 1.1 }
616    
617     /**
618 jsr166 1.33 * A deserialized/reserialized map equals original
619 dl 1.1 */
620 jsr166 1.10 public void testSerialization() throws Exception {
621 jsr166 1.21 NavigableMap x = map5();
622     NavigableMap y = serialClone(x);
623 dl 1.1
624 jsr166 1.27 assertNotSame(x, y);
625 jsr166 1.21 assertEquals(x.size(), y.size());
626     assertEquals(x.toString(), y.toString());
627     assertEquals(x, y);
628     assertEquals(y, x);
629 dl 1.1 }
630    
631     /**
632     * subMap returns map with keys in requested range
633     */
634     public void testSubMapContents() {
635     TreeMap map = map5();
636 dl 1.4 NavigableMap sm = map.subMap(two, true, four, false);
637 dl 1.1 assertEquals(two, sm.firstKey());
638     assertEquals(three, sm.lastKey());
639     assertEquals(2, sm.size());
640     assertFalse(sm.containsKey(one));
641     assertTrue(sm.containsKey(two));
642     assertTrue(sm.containsKey(three));
643     assertFalse(sm.containsKey(four));
644     assertFalse(sm.containsKey(five));
645     Iterator i = sm.keySet().iterator();
646     Object k;
647     k = (Integer)(i.next());
648     assertEquals(two, k);
649     k = (Integer)(i.next());
650     assertEquals(three, k);
651     assertFalse(i.hasNext());
652     Iterator r = sm.descendingKeySet().iterator();
653     k = (Integer)(r.next());
654     assertEquals(three, k);
655     k = (Integer)(r.next());
656     assertEquals(two, k);
657     assertFalse(r.hasNext());
658 jsr166 1.6
659 dl 1.1 Iterator j = sm.keySet().iterator();
660     j.next();
661     j.remove();
662     assertFalse(map.containsKey(two));
663     assertEquals(4, map.size());
664     assertEquals(1, sm.size());
665     assertEquals(three, sm.firstKey());
666     assertEquals(three, sm.lastKey());
667 jsr166 1.12 assertEquals("C", sm.remove(three));
668 dl 1.1 assertTrue(sm.isEmpty());
669     assertEquals(3, map.size());
670     }
671    
672     public void testSubMapContents2() {
673     TreeMap map = map5();
674 dl 1.4 NavigableMap sm = map.subMap(two, true, three, false);
675 dl 1.1 assertEquals(1, sm.size());
676     assertEquals(two, sm.firstKey());
677     assertEquals(two, sm.lastKey());
678     assertFalse(sm.containsKey(one));
679     assertTrue(sm.containsKey(two));
680     assertFalse(sm.containsKey(three));
681     assertFalse(sm.containsKey(four));
682     assertFalse(sm.containsKey(five));
683     Iterator i = sm.keySet().iterator();
684     Object k;
685     k = (Integer)(i.next());
686     assertEquals(two, k);
687     assertFalse(i.hasNext());
688     Iterator r = sm.descendingKeySet().iterator();
689     k = (Integer)(r.next());
690     assertEquals(two, k);
691     assertFalse(r.hasNext());
692 jsr166 1.6
693 dl 1.1 Iterator j = sm.keySet().iterator();
694     j.next();
695     j.remove();
696     assertFalse(map.containsKey(two));
697     assertEquals(4, map.size());
698     assertEquals(0, sm.size());
699     assertTrue(sm.isEmpty());
700 jsr166 1.12 assertSame(sm.remove(three), null);
701 dl 1.1 assertEquals(4, map.size());
702     }
703    
704     /**
705     * headMap returns map with keys in requested range
706     */
707     public void testHeadMapContents() {
708     TreeMap map = map5();
709 dl 1.4 NavigableMap sm = map.headMap(four, false);
710 dl 1.1 assertTrue(sm.containsKey(one));
711     assertTrue(sm.containsKey(two));
712     assertTrue(sm.containsKey(three));
713     assertFalse(sm.containsKey(four));
714     assertFalse(sm.containsKey(five));
715     Iterator i = sm.keySet().iterator();
716     Object k;
717     k = (Integer)(i.next());
718     assertEquals(one, k);
719     k = (Integer)(i.next());
720     assertEquals(two, k);
721     k = (Integer)(i.next());
722     assertEquals(three, k);
723     assertFalse(i.hasNext());
724     sm.clear();
725     assertTrue(sm.isEmpty());
726     assertEquals(2, map.size());
727     assertEquals(four, map.firstKey());
728     }
729    
730     /**
731     * headMap returns map with keys in requested range
732     */
733     public void testTailMapContents() {
734     TreeMap map = map5();
735 dl 1.4 NavigableMap sm = map.tailMap(two, true);
736 dl 1.1 assertFalse(sm.containsKey(one));
737     assertTrue(sm.containsKey(two));
738     assertTrue(sm.containsKey(three));
739     assertTrue(sm.containsKey(four));
740     assertTrue(sm.containsKey(five));
741     Iterator i = sm.keySet().iterator();
742     Object k;
743     k = (Integer)(i.next());
744     assertEquals(two, k);
745     k = (Integer)(i.next());
746     assertEquals(three, k);
747     k = (Integer)(i.next());
748     assertEquals(four, k);
749     k = (Integer)(i.next());
750     assertEquals(five, k);
751     assertFalse(i.hasNext());
752     Iterator r = sm.descendingKeySet().iterator();
753     k = (Integer)(r.next());
754     assertEquals(five, k);
755     k = (Integer)(r.next());
756     assertEquals(four, k);
757     k = (Integer)(r.next());
758     assertEquals(three, k);
759     k = (Integer)(r.next());
760     assertEquals(two, k);
761     assertFalse(r.hasNext());
762    
763     Iterator ei = sm.entrySet().iterator();
764     Map.Entry e;
765     e = (Map.Entry)(ei.next());
766     assertEquals(two, e.getKey());
767     assertEquals("B", e.getValue());
768     e = (Map.Entry)(ei.next());
769     assertEquals(three, e.getKey());
770     assertEquals("C", e.getValue());
771     e = (Map.Entry)(ei.next());
772     assertEquals(four, e.getKey());
773     assertEquals("D", e.getValue());
774     e = (Map.Entry)(ei.next());
775     assertEquals(five, e.getKey());
776     assertEquals("E", e.getValue());
777     assertFalse(i.hasNext());
778    
779 dl 1.4 NavigableMap ssm = sm.tailMap(four, true);
780 dl 1.1 assertEquals(four, ssm.firstKey());
781     assertEquals(five, ssm.lastKey());
782 jsr166 1.12 assertEquals("D", ssm.remove(four));
783 dl 1.1 assertEquals(1, ssm.size());
784     assertEquals(3, sm.size());
785     assertEquals(4, map.size());
786     }
787 dl 1.3
788     Random rnd = new Random(666);
789     BitSet bs;
790    
791     /**
792     * Submaps of submaps subdivide correctly
793     */
794 jsr166 1.11 public void testRecursiveSubMaps() throws Exception {
795 jsr166 1.17 int mapSize = expensiveTests ? 1000 : 100;
796 jsr166 1.9 Class cl = TreeMap.class;
797 dl 1.3 NavigableMap<Integer, Integer> map = newMap(cl);
798     bs = new BitSet(mapSize);
799    
800     populate(map, mapSize);
801     check(map, 0, mapSize - 1, true);
802     check(map.descendingMap(), 0, mapSize - 1, false);
803    
804     mutateMap(map, 0, mapSize - 1);
805     check(map, 0, mapSize - 1, true);
806     check(map.descendingMap(), 0, mapSize - 1, false);
807    
808 dl 1.4 bashSubMap(map.subMap(0, true, mapSize, false),
809 dl 1.3 0, mapSize - 1, true);
810     }
811    
812 jsr166 1.11 static NavigableMap<Integer, Integer> newMap(Class cl) throws Exception {
813     NavigableMap<Integer, Integer> result
814 jsr166 1.32 = (NavigableMap<Integer, Integer>) cl.getConstructor().newInstance();
815 jsr166 1.22 assertEquals(0, result.size());
816 dl 1.3 assertFalse(result.keySet().iterator().hasNext());
817     return result;
818     }
819    
820     void populate(NavigableMap<Integer, Integer> map, int limit) {
821     for (int i = 0, n = 2 * limit / 3; i < n; i++) {
822     int key = rnd.nextInt(limit);
823     put(map, key);
824     }
825     }
826    
827     void mutateMap(NavigableMap<Integer, Integer> map, int min, int max) {
828     int size = map.size();
829     int rangeSize = max - min + 1;
830    
831     // Remove a bunch of entries directly
832     for (int i = 0, n = rangeSize / 2; i < n; i++) {
833     remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
834     }
835    
836     // Remove a bunch of entries with iterator
837 jsr166 1.7 for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
838 dl 1.3 if (rnd.nextBoolean()) {
839     bs.clear(it.next());
840     it.remove();
841     }
842     }
843    
844     // Add entries till we're back to original size
845     while (map.size() < size) {
846     int key = min + rnd.nextInt(rangeSize);
847 jsr166 1.29 assertTrue(key >= min && key <= max);
848 dl 1.3 put(map, key);
849     }
850     }
851    
852     void mutateSubMap(NavigableMap<Integer, Integer> map, int min, int max) {
853     int size = map.size();
854     int rangeSize = max - min + 1;
855    
856     // Remove a bunch of entries directly
857     for (int i = 0, n = rangeSize / 2; i < n; i++) {
858     remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
859     }
860    
861     // Remove a bunch of entries with iterator
862 jsr166 1.7 for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
863 dl 1.3 if (rnd.nextBoolean()) {
864     bs.clear(it.next());
865     it.remove();
866     }
867     }
868    
869     // Add entries till we're back to original size
870     while (map.size() < size) {
871     int key = min - 5 + rnd.nextInt(rangeSize + 10);
872 jsr166 1.29 if (key >= min && key <= max) {
873 dl 1.3 put(map, key);
874     } else {
875     try {
876     map.put(key, 2 * key);
877 jsr166 1.11 shouldThrow();
878     } catch (IllegalArgumentException success) {}
879 dl 1.3 }
880     }
881     }
882    
883     void put(NavigableMap<Integer, Integer> map, int key) {
884     if (map.put(key, 2 * key) == null)
885     bs.set(key);
886     }
887    
888     void remove(NavigableMap<Integer, Integer> map, int key) {
889     if (map.remove(key) != null)
890     bs.clear(key);
891     }
892    
893     void bashSubMap(NavigableMap<Integer, Integer> map,
894     int min, int max, boolean ascending) {
895     check(map, min, max, ascending);
896     check(map.descendingMap(), min, max, !ascending);
897    
898     mutateSubMap(map, min, max);
899     check(map, min, max, ascending);
900     check(map.descendingMap(), min, max, !ascending);
901    
902     // Recurse
903     if (max - min < 2)
904     return;
905     int midPoint = (min + max) / 2;
906    
907     // headMap - pick direction and endpoint inclusion randomly
908     boolean incl = rnd.nextBoolean();
909 dl 1.4 NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
910 dl 1.3 if (ascending) {
911     if (rnd.nextBoolean())
912     bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true);
913     else
914     bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1),
915     false);
916     } else {
917     if (rnd.nextBoolean())
918     bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false);
919     else
920     bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max,
921     true);
922     }
923    
924     // tailMap - pick direction and endpoint inclusion randomly
925     incl = rnd.nextBoolean();
926 dl 1.4 NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
927 dl 1.3 if (ascending) {
928     if (rnd.nextBoolean())
929     bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true);
930     else
931     bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max,
932     false);
933     } else {
934     if (rnd.nextBoolean()) {
935     bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false);
936     } else {
937     bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1),
938     true);
939     }
940     }
941    
942     // subMap - pick direction and endpoint inclusion randomly
943     int rangeSize = max - min + 1;
944     int[] endpoints = new int[2];
945     endpoints[0] = min + rnd.nextInt(rangeSize);
946     endpoints[1] = min + rnd.nextInt(rangeSize);
947     Arrays.sort(endpoints);
948     boolean lowIncl = rnd.nextBoolean();
949     boolean highIncl = rnd.nextBoolean();
950     if (ascending) {
951 dl 1.4 NavigableMap<Integer,Integer> sm = map.subMap(
952 dl 1.3 endpoints[0], lowIncl, endpoints[1], highIncl);
953     if (rnd.nextBoolean())
954     bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
955     endpoints[1] - (highIncl ? 0 : 1), true);
956     else
957     bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
958     endpoints[1] - (highIncl ? 0 : 1), false);
959     } else {
960 dl 1.4 NavigableMap<Integer,Integer> sm = map.subMap(
961 dl 1.3 endpoints[1], highIncl, endpoints[0], lowIncl);
962     if (rnd.nextBoolean())
963     bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
964     endpoints[1] - (highIncl ? 0 : 1), false);
965     else
966     bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
967     endpoints[1] - (highIncl ? 0 : 1), true);
968     }
969     }
970    
971     /**
972     * min and max are both inclusive. If max < min, interval is empty.
973     */
974     void check(NavigableMap<Integer, Integer> map,
975     final int min, final int max, final boolean ascending) {
976 jsr166 1.19 class ReferenceSet {
977 dl 1.3 int lower(int key) {
978     return ascending ? lowerAscending(key) : higherAscending(key);
979     }
980     int floor(int key) {
981     return ascending ? floorAscending(key) : ceilingAscending(key);
982     }
983     int ceiling(int key) {
984     return ascending ? ceilingAscending(key) : floorAscending(key);
985     }
986     int higher(int key) {
987     return ascending ? higherAscending(key) : lowerAscending(key);
988     }
989     int first() {
990     return ascending ? firstAscending() : lastAscending();
991     }
992     int last() {
993     return ascending ? lastAscending() : firstAscending();
994     }
995     int lowerAscending(int key) {
996     return floorAscending(key - 1);
997     }
998     int floorAscending(int key) {
999     if (key < min)
1000     return -1;
1001     else if (key > max)
1002     key = max;
1003    
1004     // BitSet should support this! Test would run much faster
1005     while (key >= min) {
1006     if (bs.get(key))
1007 jsr166 1.15 return key;
1008 dl 1.3 key--;
1009     }
1010     return -1;
1011     }
1012     int ceilingAscending(int key) {
1013     if (key < min)
1014     key = min;
1015     else if (key > max)
1016     return -1;
1017     int result = bs.nextSetBit(key);
1018     return result > max ? -1 : result;
1019     }
1020     int higherAscending(int key) {
1021     return ceilingAscending(key + 1);
1022     }
1023     private int firstAscending() {
1024     int result = ceilingAscending(min);
1025     return result > max ? -1 : result;
1026     }
1027     private int lastAscending() {
1028     int result = floorAscending(max);
1029     return result < min ? -1 : result;
1030     }
1031     }
1032     ReferenceSet rs = new ReferenceSet();
1033    
1034     // Test contents using containsKey
1035     int size = 0;
1036     for (int i = min; i <= max; i++) {
1037     boolean bsContainsI = bs.get(i);
1038     assertEquals(bsContainsI, map.containsKey(i));
1039     if (bsContainsI)
1040     size++;
1041     }
1042 jsr166 1.23 assertEquals(size, map.size());
1043 dl 1.3
1044     // Test contents using contains keySet iterator
1045     int size2 = 0;
1046     int previousKey = -1;
1047     for (int key : map.keySet()) {
1048     assertTrue(bs.get(key));
1049     size2++;
1050     assertTrue(previousKey < 0 ||
1051     (ascending ? key - previousKey > 0 : key - previousKey < 0));
1052     previousKey = key;
1053     }
1054     assertEquals(size2, size);
1055    
1056     // Test navigation ops
1057     for (int key = min - 1; key <= max + 1; key++) {
1058     assertEq(map.lowerKey(key), rs.lower(key));
1059     assertEq(map.floorKey(key), rs.floor(key));
1060     assertEq(map.higherKey(key), rs.higher(key));
1061     assertEq(map.ceilingKey(key), rs.ceiling(key));
1062     }
1063    
1064     // Test extrema
1065     if (map.size() != 0) {
1066     assertEq(map.firstKey(), rs.first());
1067     assertEq(map.lastKey(), rs.last());
1068     } else {
1069     assertEq(rs.first(), -1);
1070     assertEq(rs.last(), -1);
1071     try {
1072     map.firstKey();
1073 jsr166 1.11 shouldThrow();
1074     } catch (NoSuchElementException success) {}
1075 dl 1.3 try {
1076     map.lastKey();
1077 jsr166 1.11 shouldThrow();
1078     } catch (NoSuchElementException success) {}
1079 dl 1.3 }
1080     }
1081    
1082     static void assertEq(Integer i, int j) {
1083     if (i == null)
1084     assertEquals(j, -1);
1085     else
1086     assertEquals((int) i, j);
1087     }
1088    
1089     static boolean eq(Integer i, int j) {
1090     return i == null ? j == -1 : i == j;
1091     }
1092 jsr166 1.6
1093 dl 1.1 }