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

File Contents

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