/src/test/tck/TreeMapTest.java

https://github.com/dmlloyd/jsr166 · Java · 1072 lines · 807 code · 108 blank · 157 comment · 71 complexity · 87a9488136129322d43e480ddae8a5f7 MD5 · raw file

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