ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/TreeMapTest.java
Revision: 1.18
Committed: Tue Mar 15 19:47:07 2011 UTC (13 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.17: +1 -1 lines
Log Message:
Update Creative Commons license URL in legal notices

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