ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/TreeMapTest.java
Revision: 1.10
Committed: Sat Nov 21 10:25:05 2009 UTC (14 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.9: +12 -17 lines
Log Message:
improve exception handling

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     * http://creativecommons.org/licenses/publicdomain
5     */
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.9 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     * clear removes all pairs
38     */
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     * Maps with same contents are equal
56     */
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     * containsKey returns true for contained key
69     */
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     * containsValue returns true for held values
78     */
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     * get returns the correct element at the given key,
87     * or null if not present
88     */
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     * isEmpty is true of empty map and false for non-empty
98     */
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     * firstKey returns first key
108     */
109     public void testFirstKey() {
110     TreeMap map = map5();
111 jsr166 1.9 assertEquals(one, map.firstKey());
112 dl 1.1 }
113    
114     /**
115     * lastKey returns last key
116     */
117     public void testLastKey() {
118     TreeMap map = map5();
119 jsr166 1.9 assertEquals(five, map.lastKey());
120 dl 1.1 }
121    
122    
123     /**
124     * keySet.toArray returns contains all keys
125     */
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     * descendingkeySet.toArray returns contains all keys
138     */
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     * keySet returns a Set containing all the keys
151     */
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     * keySet is ordered
165     */
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     * descendingKeySet is ordered
203     */
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     * descending iterator of descendingKeySet is ordered
222     */
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     * entrySet.toArray contains all entries
293     */
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     * descendingEntrySet.toArray contains all entries
307     */
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     * putAll adds all key-value pairs from the given map
321     */
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     * remove removes the correct key-value pair from the map
336     */
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     /**
364     * higherEntry returns next entry.
365     */
366     public void testHigherEntry() {
367     TreeMap map = map5();
368     Map.Entry e1 = map.higherEntry(three);
369     assertEquals(four, e1.getKey());
370    
371     Map.Entry e2 = map.higherEntry(zero);
372     assertEquals(one, e2.getKey());
373    
374     Map.Entry e3 = map.higherEntry(five);
375     assertNull(e3);
376    
377     Map.Entry e4 = map.higherEntry(six);
378     assertNull(e4);
379    
380     }
381    
382     /**
383     * floorEntry returns preceding entry.
384     */
385     public void testFloorEntry() {
386     TreeMap map = map5();
387     Map.Entry e1 = map.floorEntry(three);
388     assertEquals(three, e1.getKey());
389    
390     Map.Entry e2 = map.floorEntry(six);
391     assertEquals(five, e2.getKey());
392    
393     Map.Entry e3 = map.floorEntry(one);
394     assertEquals(one, e3.getKey());
395    
396     Map.Entry e4 = map.floorEntry(zero);
397     assertNull(e4);
398    
399     }
400    
401     /**
402     * ceilingEntry returns next entry.
403     */
404     public void testCeilingEntry() {
405     TreeMap map = map5();
406     Map.Entry e1 = map.ceilingEntry(three);
407     assertEquals(three, e1.getKey());
408    
409     Map.Entry e2 = map.ceilingEntry(zero);
410     assertEquals(one, e2.getKey());
411    
412     Map.Entry e3 = map.ceilingEntry(five);
413     assertEquals(five, e3.getKey());
414    
415     Map.Entry e4 = map.ceilingEntry(six);
416     assertNull(e4);
417    
418     }
419    
420    
421     /**
422     * lowerKey returns preceding element
423     */
424     public void testLowerKey() {
425     TreeMap q = map5();
426     Object e1 = q.lowerKey(three);
427     assertEquals(two, e1);
428    
429     Object e2 = q.lowerKey(six);
430     assertEquals(five, e2);
431    
432     Object e3 = q.lowerKey(one);
433     assertNull(e3);
434    
435     Object e4 = q.lowerKey(zero);
436     assertNull(e4);
437    
438     }
439    
440     /**
441     * higherKey returns next element
442     */
443     public void testHigherKey() {
444     TreeMap q = map5();
445     Object e1 = q.higherKey(three);
446     assertEquals(four, e1);
447    
448     Object e2 = q.higherKey(zero);
449     assertEquals(one, e2);
450    
451     Object e3 = q.higherKey(five);
452     assertNull(e3);
453    
454     Object e4 = q.higherKey(six);
455     assertNull(e4);
456    
457     }
458    
459     /**
460     * floorKey returns preceding element
461     */
462     public void testFloorKey() {
463     TreeMap q = map5();
464     Object e1 = q.floorKey(three);
465     assertEquals(three, e1);
466    
467     Object e2 = q.floorKey(six);
468     assertEquals(five, e2);
469    
470     Object e3 = q.floorKey(one);
471     assertEquals(one, e3);
472    
473     Object e4 = q.floorKey(zero);
474     assertNull(e4);
475    
476     }
477    
478     /**
479     * ceilingKey returns next element
480     */
481     public void testCeilingKey() {
482     TreeMap q = map5();
483     Object e1 = q.ceilingKey(three);
484     assertEquals(three, e1);
485    
486     Object e2 = q.ceilingKey(zero);
487     assertEquals(one, e2);
488    
489     Object e3 = q.ceilingKey(five);
490     assertEquals(five, e3);
491    
492     Object e4 = q.ceilingKey(six);
493     assertNull(e4);
494    
495     }
496    
497     /**
498     * pollFirstEntry returns entries in order
499     */
500     public void testPollFirstEntry() {
501     TreeMap map = map5();
502     Map.Entry e = map.pollFirstEntry();
503     assertEquals(one, e.getKey());
504     assertEquals("A", e.getValue());
505     e = map.pollFirstEntry();
506     assertEquals(two, e.getKey());
507     map.put(one, "A");
508     e = map.pollFirstEntry();
509     assertEquals(one, e.getKey());
510     assertEquals("A", e.getValue());
511     e = map.pollFirstEntry();
512     assertEquals(three, e.getKey());
513     map.remove(four);
514     e = map.pollFirstEntry();
515     assertEquals(five, e.getKey());
516     try {
517     e.setValue("A");
518     shouldThrow();
519     } catch (Exception ok) {
520     }
521     e = map.pollFirstEntry();
522     assertNull(e);
523     }
524    
525     /**
526     * pollLastEntry returns entries in order
527     */
528     public void testPollLastEntry() {
529     TreeMap map = map5();
530     Map.Entry e = map.pollLastEntry();
531     assertEquals(five, e.getKey());
532     assertEquals("E", e.getValue());
533     e = map.pollLastEntry();
534     assertEquals(four, e.getKey());
535     map.put(five, "E");
536     e = map.pollLastEntry();
537     assertEquals(five, e.getKey());
538     assertEquals("E", e.getValue());
539     e = map.pollLastEntry();
540     assertEquals(three, e.getKey());
541     map.remove(two);
542     e = map.pollLastEntry();
543     assertEquals(one, e.getKey());
544     try {
545     e.setValue("E");
546     shouldThrow();
547     } catch (Exception ok) {
548     }
549     e = map.pollLastEntry();
550     assertNull(e);
551     }
552    
553     /**
554     * size returns the correct values
555     */
556     public void testSize() {
557     TreeMap map = map5();
558     TreeMap empty = new TreeMap();
559 jsr166 1.9 assertEquals(0, empty.size());
560     assertEquals(5, map.size());
561 dl 1.1 }
562    
563     /**
564     * toString contains toString of elements
565     */
566     public void testToString() {
567     TreeMap map = map5();
568     String s = map.toString();
569     for (int i = 1; i <= 5; ++i) {
570     assertTrue(s.indexOf(String.valueOf(i)) >= 0);
571     }
572 jsr166 1.6 }
573 dl 1.1
574     // Exception tests
575    
576     /**
577     * get(null) of nonempty map throws NPE
578     */
579     public void testGet_NullPointerException() {
580     try {
581     TreeMap c = map5();
582     c.get(null);
583     shouldThrow();
584 jsr166 1.8 } catch (NullPointerException e) {}
585 dl 1.1 }
586    
587     /**
588     * containsKey(null) of nonempty map throws NPE
589     */
590     public void testContainsKey_NullPointerException() {
591     try {
592     TreeMap c = map5();
593     c.containsKey(null);
594     shouldThrow();
595 jsr166 1.8 } catch (NullPointerException e) {}
596 dl 1.1 }
597    
598     /**
599     * remove(null) throws NPE for nonempty map
600     */
601     public void testRemove1_NullPointerException() {
602     try {
603     TreeMap c = new TreeMap();
604     c.put("sadsdf", "asdads");
605     c.remove(null);
606     shouldThrow();
607 jsr166 1.8 } catch (NullPointerException e) {}
608 dl 1.1 }
609    
610     /**
611     * A deserialized map equals original
612     */
613 jsr166 1.10 public void testSerialization() throws Exception {
614 dl 1.1 TreeMap q = map5();
615    
616 jsr166 1.10 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
617     ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
618     out.writeObject(q);
619     out.close();
620    
621     ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
622     ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
623     TreeMap r = (TreeMap)in.readObject();
624     assertEquals(q.size(), r.size());
625     assertTrue(q.equals(r));
626     assertTrue(r.equals(q));
627 dl 1.1 }
628    
629     /**
630     * subMap returns map with keys in requested range
631     */
632     public void testSubMapContents() {
633     TreeMap map = map5();
634 dl 1.4 NavigableMap sm = map.subMap(two, true, four, false);
635 dl 1.1 assertEquals(two, sm.firstKey());
636     assertEquals(three, sm.lastKey());
637     assertEquals(2, sm.size());
638     assertFalse(sm.containsKey(one));
639     assertTrue(sm.containsKey(two));
640     assertTrue(sm.containsKey(three));
641     assertFalse(sm.containsKey(four));
642     assertFalse(sm.containsKey(five));
643     Iterator i = sm.keySet().iterator();
644     Object k;
645     k = (Integer)(i.next());
646     assertEquals(two, k);
647     k = (Integer)(i.next());
648     assertEquals(three, k);
649     assertFalse(i.hasNext());
650     Iterator r = sm.descendingKeySet().iterator();
651     k = (Integer)(r.next());
652     assertEquals(three, k);
653     k = (Integer)(r.next());
654     assertEquals(two, k);
655     assertFalse(r.hasNext());
656 jsr166 1.6
657 dl 1.1 Iterator j = sm.keySet().iterator();
658     j.next();
659     j.remove();
660     assertFalse(map.containsKey(two));
661     assertEquals(4, map.size());
662     assertEquals(1, sm.size());
663     assertEquals(three, sm.firstKey());
664     assertEquals(three, sm.lastKey());
665     assertTrue(sm.remove(three) != null);
666     assertTrue(sm.isEmpty());
667     assertEquals(3, map.size());
668     }
669    
670     public void testSubMapContents2() {
671     TreeMap map = map5();
672 dl 1.4 NavigableMap sm = map.subMap(two, true, three, false);
673 dl 1.1 assertEquals(1, sm.size());
674     assertEquals(two, sm.firstKey());
675     assertEquals(two, sm.lastKey());
676     assertFalse(sm.containsKey(one));
677     assertTrue(sm.containsKey(two));
678     assertFalse(sm.containsKey(three));
679     assertFalse(sm.containsKey(four));
680     assertFalse(sm.containsKey(five));
681     Iterator i = sm.keySet().iterator();
682     Object k;
683     k = (Integer)(i.next());
684     assertEquals(two, k);
685     assertFalse(i.hasNext());
686     Iterator r = sm.descendingKeySet().iterator();
687     k = (Integer)(r.next());
688     assertEquals(two, k);
689     assertFalse(r.hasNext());
690 jsr166 1.6
691 dl 1.1 Iterator j = sm.keySet().iterator();
692     j.next();
693     j.remove();
694     assertFalse(map.containsKey(two));
695     assertEquals(4, map.size());
696     assertEquals(0, sm.size());
697     assertTrue(sm.isEmpty());
698     assertTrue(sm.remove(three) == null);
699     assertEquals(4, map.size());
700     }
701    
702     /**
703     * headMap returns map with keys in requested range
704     */
705     public void testHeadMapContents() {
706     TreeMap map = map5();
707 dl 1.4 NavigableMap sm = map.headMap(four, false);
708 dl 1.1 assertTrue(sm.containsKey(one));
709     assertTrue(sm.containsKey(two));
710     assertTrue(sm.containsKey(three));
711     assertFalse(sm.containsKey(four));
712     assertFalse(sm.containsKey(five));
713     Iterator i = sm.keySet().iterator();
714     Object k;
715     k = (Integer)(i.next());
716     assertEquals(one, k);
717     k = (Integer)(i.next());
718     assertEquals(two, k);
719     k = (Integer)(i.next());
720     assertEquals(three, k);
721     assertFalse(i.hasNext());
722     sm.clear();
723     assertTrue(sm.isEmpty());
724     assertEquals(2, map.size());
725     assertEquals(four, map.firstKey());
726     }
727    
728     /**
729     * headMap returns map with keys in requested range
730     */
731     public void testTailMapContents() {
732     TreeMap map = map5();
733 dl 1.4 NavigableMap sm = map.tailMap(two, true);
734 dl 1.1 assertFalse(sm.containsKey(one));
735     assertTrue(sm.containsKey(two));
736     assertTrue(sm.containsKey(three));
737     assertTrue(sm.containsKey(four));
738     assertTrue(sm.containsKey(five));
739     Iterator i = sm.keySet().iterator();
740     Object k;
741     k = (Integer)(i.next());
742     assertEquals(two, k);
743     k = (Integer)(i.next());
744     assertEquals(three, k);
745     k = (Integer)(i.next());
746     assertEquals(four, k);
747     k = (Integer)(i.next());
748     assertEquals(five, k);
749     assertFalse(i.hasNext());
750     Iterator r = sm.descendingKeySet().iterator();
751     k = (Integer)(r.next());
752     assertEquals(five, k);
753     k = (Integer)(r.next());
754     assertEquals(four, k);
755     k = (Integer)(r.next());
756     assertEquals(three, k);
757     k = (Integer)(r.next());
758     assertEquals(two, k);
759     assertFalse(r.hasNext());
760    
761     Iterator ei = sm.entrySet().iterator();
762     Map.Entry e;
763     e = (Map.Entry)(ei.next());
764     assertEquals(two, e.getKey());
765     assertEquals("B", e.getValue());
766     e = (Map.Entry)(ei.next());
767     assertEquals(three, e.getKey());
768     assertEquals("C", e.getValue());
769     e = (Map.Entry)(ei.next());
770     assertEquals(four, e.getKey());
771     assertEquals("D", e.getValue());
772     e = (Map.Entry)(ei.next());
773     assertEquals(five, e.getKey());
774     assertEquals("E", e.getValue());
775     assertFalse(i.hasNext());
776    
777 dl 1.4 NavigableMap ssm = sm.tailMap(four, true);
778 dl 1.1 assertEquals(four, ssm.firstKey());
779     assertEquals(five, ssm.lastKey());
780     assertTrue(ssm.remove(four) != null);
781     assertEquals(1, ssm.size());
782     assertEquals(3, sm.size());
783     assertEquals(4, map.size());
784     }
785 dl 1.3
786     Random rnd = new Random(666);
787     BitSet bs;
788    
789     /**
790     * Submaps of submaps subdivide correctly
791     */
792     public void testRecursiveSubMaps() {
793 jsr166 1.9 int mapSize = 1000;
794     Class cl = TreeMap.class;
795 dl 1.3 NavigableMap<Integer, Integer> map = newMap(cl);
796     bs = new BitSet(mapSize);
797    
798     populate(map, mapSize);
799     check(map, 0, mapSize - 1, true);
800     check(map.descendingMap(), 0, mapSize - 1, false);
801    
802     mutateMap(map, 0, mapSize - 1);
803     check(map, 0, mapSize - 1, true);
804     check(map.descendingMap(), 0, mapSize - 1, false);
805    
806 dl 1.4 bashSubMap(map.subMap(0, true, mapSize, false),
807 dl 1.3 0, mapSize - 1, true);
808     }
809    
810     static NavigableMap<Integer, Integer> newMap(Class cl) {
811     NavigableMap<Integer, Integer> result = null;
812 jsr166 1.9 try {
813 dl 1.3 result = (NavigableMap<Integer, Integer>) cl.newInstance();
814 jsr166 1.9 } catch (Exception e) {
815 dl 1.3 fail();
816 jsr166 1.9 }
817 dl 1.3 assertEquals(result.size(), 0);
818     assertFalse(result.keySet().iterator().hasNext());
819     return result;
820     }
821    
822     void populate(NavigableMap<Integer, Integer> map, int limit) {
823     for (int i = 0, n = 2 * limit / 3; i < n; i++) {
824     int key = rnd.nextInt(limit);
825     put(map, key);
826     }
827     }
828    
829     void mutateMap(NavigableMap<Integer, Integer> map, int min, int max) {
830     int size = map.size();
831     int rangeSize = max - min + 1;
832    
833     // Remove a bunch of entries directly
834     for (int i = 0, n = rangeSize / 2; i < n; i++) {
835     remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
836     }
837    
838     // Remove a bunch of entries with iterator
839 jsr166 1.7 for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
840 dl 1.3 if (rnd.nextBoolean()) {
841     bs.clear(it.next());
842     it.remove();
843     }
844     }
845    
846     // Add entries till we're back to original size
847     while (map.size() < size) {
848     int key = min + rnd.nextInt(rangeSize);
849     assertTrue(key >= min && key<= max);
850     put(map, key);
851     }
852     }
853    
854     void mutateSubMap(NavigableMap<Integer, Integer> map, int min, int max) {
855     int size = map.size();
856     int rangeSize = max - min + 1;
857    
858     // Remove a bunch of entries directly
859     for (int i = 0, n = rangeSize / 2; i < n; i++) {
860     remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
861     }
862    
863     // Remove a bunch of entries with iterator
864 jsr166 1.7 for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
865 dl 1.3 if (rnd.nextBoolean()) {
866     bs.clear(it.next());
867     it.remove();
868     }
869     }
870    
871     // Add entries till we're back to original size
872     while (map.size() < size) {
873     int key = min - 5 + rnd.nextInt(rangeSize + 10);
874     if (key >= min && key<= max) {
875     put(map, key);
876     } else {
877     try {
878     map.put(key, 2 * key);
879     fail();
880 jsr166 1.7 } catch (IllegalArgumentException e) {
881 dl 1.3 // expected
882     }
883     }
884     }
885     }
886    
887     void put(NavigableMap<Integer, Integer> map, int key) {
888     if (map.put(key, 2 * key) == null)
889     bs.set(key);
890     }
891    
892     void remove(NavigableMap<Integer, Integer> map, int key) {
893     if (map.remove(key) != null)
894     bs.clear(key);
895     }
896    
897     void bashSubMap(NavigableMap<Integer, Integer> map,
898     int min, int max, boolean ascending) {
899     check(map, min, max, ascending);
900     check(map.descendingMap(), min, max, !ascending);
901    
902     mutateSubMap(map, min, max);
903     check(map, min, max, ascending);
904     check(map.descendingMap(), min, max, !ascending);
905    
906     // Recurse
907     if (max - min < 2)
908     return;
909     int midPoint = (min + max) / 2;
910    
911     // headMap - pick direction and endpoint inclusion randomly
912     boolean incl = rnd.nextBoolean();
913 dl 1.4 NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
914 dl 1.3 if (ascending) {
915     if (rnd.nextBoolean())
916     bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true);
917     else
918     bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1),
919     false);
920     } else {
921     if (rnd.nextBoolean())
922     bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false);
923     else
924     bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max,
925     true);
926     }
927    
928     // tailMap - pick direction and endpoint inclusion randomly
929     incl = rnd.nextBoolean();
930 dl 1.4 NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
931 dl 1.3 if (ascending) {
932     if (rnd.nextBoolean())
933     bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true);
934     else
935     bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max,
936     false);
937     } else {
938     if (rnd.nextBoolean()) {
939     bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false);
940     } else {
941     bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1),
942     true);
943     }
944     }
945    
946     // subMap - pick direction and endpoint inclusion randomly
947     int rangeSize = max - min + 1;
948     int[] endpoints = new int[2];
949     endpoints[0] = min + rnd.nextInt(rangeSize);
950     endpoints[1] = min + rnd.nextInt(rangeSize);
951     Arrays.sort(endpoints);
952     boolean lowIncl = rnd.nextBoolean();
953     boolean highIncl = rnd.nextBoolean();
954     if (ascending) {
955 dl 1.4 NavigableMap<Integer,Integer> sm = map.subMap(
956 dl 1.3 endpoints[0], lowIncl, endpoints[1], highIncl);
957     if (rnd.nextBoolean())
958     bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
959     endpoints[1] - (highIncl ? 0 : 1), true);
960     else
961     bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
962     endpoints[1] - (highIncl ? 0 : 1), false);
963     } else {
964 dl 1.4 NavigableMap<Integer,Integer> sm = map.subMap(
965 dl 1.3 endpoints[1], highIncl, endpoints[0], lowIncl);
966     if (rnd.nextBoolean())
967     bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
968     endpoints[1] - (highIncl ? 0 : 1), false);
969     else
970     bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
971     endpoints[1] - (highIncl ? 0 : 1), true);
972     }
973     }
974    
975     /**
976     * min and max are both inclusive. If max < min, interval is empty.
977     */
978     void check(NavigableMap<Integer, Integer> map,
979     final int min, final int max, final boolean ascending) {
980     class ReferenceSet {
981     int lower(int key) {
982     return ascending ? lowerAscending(key) : higherAscending(key);
983     }
984     int floor(int key) {
985     return ascending ? floorAscending(key) : ceilingAscending(key);
986     }
987     int ceiling(int key) {
988     return ascending ? ceilingAscending(key) : floorAscending(key);
989     }
990     int higher(int key) {
991     return ascending ? higherAscending(key) : lowerAscending(key);
992     }
993     int first() {
994     return ascending ? firstAscending() : lastAscending();
995     }
996     int last() {
997     return ascending ? lastAscending() : firstAscending();
998     }
999     int lowerAscending(int key) {
1000     return floorAscending(key - 1);
1001     }
1002     int floorAscending(int key) {
1003     if (key < min)
1004     return -1;
1005     else if (key > max)
1006     key = max;
1007    
1008     // BitSet should support this! Test would run much faster
1009     while (key >= min) {
1010     if (bs.get(key))
1011     return(key);
1012     key--;
1013     }
1014     return -1;
1015     }
1016     int ceilingAscending(int key) {
1017     if (key < min)
1018     key = min;
1019     else if (key > max)
1020     return -1;
1021     int result = bs.nextSetBit(key);
1022     return result > max ? -1 : result;
1023     }
1024     int higherAscending(int key) {
1025     return ceilingAscending(key + 1);
1026     }
1027     private int firstAscending() {
1028     int result = ceilingAscending(min);
1029     return result > max ? -1 : result;
1030     }
1031     private int lastAscending() {
1032     int result = floorAscending(max);
1033     return result < min ? -1 : result;
1034     }
1035     }
1036     ReferenceSet rs = new ReferenceSet();
1037    
1038     // Test contents using containsKey
1039     int size = 0;
1040     for (int i = min; i <= max; i++) {
1041     boolean bsContainsI = bs.get(i);
1042     assertEquals(bsContainsI, map.containsKey(i));
1043     if (bsContainsI)
1044     size++;
1045     }
1046     assertEquals(map.size(), size);
1047    
1048     // Test contents using contains keySet iterator
1049     int size2 = 0;
1050     int previousKey = -1;
1051     for (int key : map.keySet()) {
1052     assertTrue(bs.get(key));
1053     size2++;
1054     assertTrue(previousKey < 0 ||
1055     (ascending ? key - previousKey > 0 : key - previousKey < 0));
1056     previousKey = key;
1057     }
1058     assertEquals(size2, size);
1059    
1060     // Test navigation ops
1061     for (int key = min - 1; key <= max + 1; key++) {
1062     assertEq(map.lowerKey(key), rs.lower(key));
1063     assertEq(map.floorKey(key), rs.floor(key));
1064     assertEq(map.higherKey(key), rs.higher(key));
1065     assertEq(map.ceilingKey(key), rs.ceiling(key));
1066     }
1067    
1068     // Test extrema
1069     if (map.size() != 0) {
1070     assertEq(map.firstKey(), rs.first());
1071     assertEq(map.lastKey(), rs.last());
1072     } else {
1073     assertEq(rs.first(), -1);
1074     assertEq(rs.last(), -1);
1075     try {
1076     map.firstKey();
1077     fail();
1078 jsr166 1.7 } catch (NoSuchElementException e) {
1079 dl 1.3 // expected
1080     }
1081     try {
1082     map.lastKey();
1083     fail();
1084 jsr166 1.7 } catch (NoSuchElementException e) {
1085 dl 1.3 // expected
1086     }
1087     }
1088     }
1089    
1090     static void assertEq(Integer i, int j) {
1091     if (i == null)
1092     assertEquals(j, -1);
1093     else
1094     assertEquals((int) i, j);
1095     }
1096    
1097     static boolean eq(Integer i, int j) {
1098     return i == null ? j == -1 : i == j;
1099     }
1100 jsr166 1.6
1101 dl 1.1 }