ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/TreeMapTest.java
Revision: 1.3
Committed: Wed Apr 19 15:10:54 2006 UTC (18 years ago) by dl
Branch: MAIN
Changes since 1.2: +322 -7 lines
Log Message:
Updated Navigable tests

File Contents

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