1. /*
  2. * @(#)TreeMap.java 1.43 00/02/02
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.util;
  11. /**
  12. * Red-Black tree based implementation of the <tt>SortedMap</tt> interface.
  13. * This class guarantees that the map will be in ascending key order, sorted
  14. * according to the <i>natural order</i> for the key's class (see
  15. * <tt>Comparable</tt>), or by the comparator provided at creation time,
  16. * depending on which constructor is used.<p>
  17. *
  18. * This implementation provides guaranteed log(n) time cost for the
  19. * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and <tt>remove</tt>
  20. * operations. Algorithms are adaptations of those in Cormen, Leiserson, and
  21. * Rivest's <I>Introduction to Algorithms</I>.<p>
  22. *
  23. * Note that the ordering maintained by a sorted map (whether or not an
  24. * explicit comparator is provided) must be <i>consistent with equals</i> if
  25. * this sorted map is to correctly implement the <tt>Map</tt> interface. (See
  26. * <tt>Comparable</tt> or <tt>Comparator</tt> for a precise definition of
  27. * <i>consistent with equals</i>.) This is so because the <tt>Map</tt>
  28. * interface is defined in terms of the equals operation, but a map performs
  29. * all key comparisons using its <tt>compareTo</tt> (or <tt>compare</tt>)
  30. * method, so two keys that are deemed equal by this method are, from the
  31. * standpoint of the sorted map, equal. The behavior of a sorted map
  32. * <i>is</i> well-defined even if its ordering is inconsistent with equals; it
  33. * just fails to obey the general contract of the <tt>Map</tt> interface.<p>
  34. *
  35. * <b>Note that this implementation is not synchronized.</b> If multiple
  36. * threads access a map concurrently, and at least one of the threads modifies
  37. * the map structurally, it <i>must</i> be synchronized externally. (A
  38. * structural modification is any operation that adds or deletes one or more
  39. * mappings; merely changing the value associated with an existing key is not
  40. * a structural modification.) This is typically accomplished by
  41. * synchronizing on some object that naturally encapsulates the map. If no
  42. * such object exists, the map should be "wrapped" using the
  43. * <tt>Collections.synchronizedMap</tt> method. This is best done at creation
  44. * time, to prevent accidental unsynchronized access to the map:
  45. * <pre>
  46. * Map m = Collections.synchronizedMap(new TreeMap(...));
  47. * </pre><p>
  48. *
  49. * The iterators returned by all of this class's "collection view methods" are
  50. * <i>fail-fast</i>: if the map is structurally modified at any time after the
  51. * iterator is created, in any way except through the iterator's own
  52. * <tt>remove</tt> or <tt>add</tt> methods, the iterator throws a
  53. * <tt>ConcurrentModificationException</tt>. Thus, in the face of concurrent
  54. * modification, the iterator fails quickly and cleanly, rather than risking
  55. * arbitrary, non-deterministic behavior at an undetermined time in the
  56. * future.
  57. *
  58. * @author Josh Bloch and Doug Lea
  59. * @version 1.43, 02/02/00
  60. * @see Map
  61. * @see HashMap
  62. * @see Hashtable
  63. * @see Comparable
  64. * @see Comparator
  65. * @see Collection
  66. * @see Collections#synchronizedMap(Map)
  67. * @since 1.2
  68. */
  69. public class TreeMap extends AbstractMap
  70. implements SortedMap, Cloneable, java.io.Serializable
  71. {
  72. /**
  73. * The Comparator used to maintain order in this TreeMap, or
  74. * null if this TreeMap uses its elements natural ordering.
  75. *
  76. * @serial
  77. */
  78. private Comparator comparator = null;
  79. private transient Entry root = null;
  80. /**
  81. * The number of entries in the tree
  82. */
  83. private transient int size = 0;
  84. /**
  85. * The number of structural modifications to the tree.
  86. */
  87. private transient int modCount = 0;
  88. private void incrementSize() { modCount++; size++; }
  89. private void decrementSize() { modCount++; size--; }
  90. /**
  91. * Constructs a new, empty map, sorted according to the keys' natural
  92. * order. All keys inserted into the map must implement the
  93. * <tt>Comparable</tt> interface. Furthermore, all such keys must be
  94. * <i>mutually comparable</i>: <tt>k1.compareTo(k2)</tt> must not throw a
  95. * ClassCastException for any elements <tt>k1</tt> and <tt>k2</tt> in the
  96. * map. If the user attempts to put a key into the map that violates this
  97. * constraint (for example, the user attempts to put a string key into a
  98. * map whose keys are integers), the <tt>put(Object key, Object
  99. * value)</tt> call will throw a <tt>ClassCastException</tt>.
  100. *
  101. * @see Comparable
  102. */
  103. public TreeMap() {
  104. }
  105. /**
  106. * Constructs a new, empty map, sorted according to the given comparator.
  107. * All keys inserted into the map must be <i>mutually comparable</i> by
  108. * the given comparator: <tt>comparator.compare(k1, k2)</tt> must not
  109. * throw a <tt>ClassCastException</tt> for any keys <tt>k1</tt> and
  110. * <tt>k2</tt> in the map. If the user attempts to put a key into the
  111. * map that violates this constraint, the <tt>put(Object key, Object
  112. * value)</tt> call will throw a <tt>ClassCastException</tt>.
  113. *
  114. * @param c the comparator that will be used to sort this map. A
  115. * <tt>null</tt> value indicates that the keys' <i>natural
  116. * ordering</i> should be used.
  117. */
  118. public TreeMap(Comparator c) {
  119. this.comparator = c;
  120. }
  121. /**
  122. * Constructs a new map containing the same mappings as the given map,
  123. * sorted according to the keys' <i>natural order</i>. All keys inserted
  124. * into the new map must implement the <tt>Comparable</tt> interface.
  125. * Furthermore, all such keys must be <i>mutually comparable</i>:
  126. * <tt>k1.compareTo(k2)</tt> must not throw a <tt>ClassCastException</tt>
  127. * for any elements <tt>k1</tt> and <tt>k2</tt> in the map. This method
  128. * runs in n*log(n) time.
  129. *
  130. * @param m the map whose mappings are to be placed in this map.
  131. * @throws ClassCastException the keys in t are not Comparable, or
  132. * are not mutually comparable.
  133. */
  134. public TreeMap(Map m) {
  135. putAll(m);
  136. }
  137. /**
  138. * Constructs a new map containing the same mappings as the given
  139. * <tt>SortedMap</tt>, sorted according to the same ordering. This method
  140. * runs in linear time.
  141. *
  142. * @param m the sorted map whose mappings are to be placed in this map,
  143. * and whose comparator is to be used to sort this map.
  144. */
  145. public TreeMap(SortedMap m) {
  146. comparator = m.comparator();
  147. try {
  148. buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
  149. } catch (java.io.IOException cannotHappen) {
  150. } catch (ClassNotFoundException cannotHappen) {
  151. }
  152. }
  153. // Query Operations
  154. /**
  155. * Returns the number of key-value mappings in this map.
  156. *
  157. * @return the number of key-value mappings in this map.
  158. */
  159. public int size() {
  160. return size;
  161. }
  162. /**
  163. * Returns <tt>true</tt> if this map contains a mapping for the specified
  164. * key.
  165. *
  166. * @param key key whose presence in this map is to be tested.
  167. *
  168. * @return <tt>true</tt> if this map contains a mapping for the
  169. * specified key.
  170. * @throws ClassCastException if the key cannot be compared with the keys
  171. * currently in the map.
  172. * @throws NullPointerException key is <tt>null</tt> and this map uses
  173. * natural ordering, or its comparator does not tolerate
  174. * <tt>null</tt> keys.
  175. */
  176. public boolean containsKey(Object key) {
  177. return getEntry(key) != null;
  178. }
  179. /**
  180. * Returns <tt>true</tt> if this map maps one or more keys to the
  181. * specified value. More formally, returns <tt>true</tt> if and only if
  182. * this map contains at least one mapping to a value <tt>v</tt> such
  183. * that <tt>(value==null ? v==null : value.equals(v))</tt>. This
  184. * operation will probably require time linear in the Map size for most
  185. * implementations of Map.
  186. *
  187. * @param value value whose presence in this Map is to be tested.
  188. * @since 1.2
  189. */
  190. public boolean containsValue(Object value) {
  191. return (root==null ? false :
  192. (value==null ? valueSearchNull(root)
  193. : valueSearchNonNull(root, value)));
  194. }
  195. private boolean valueSearchNull(Entry n) {
  196. if (n.value == null)
  197. return true;
  198. // Check left and right subtrees for value
  199. return (n.left != null && valueSearchNull(n.left)) ||
  200. (n.right != null && valueSearchNull(n.right));
  201. }
  202. private boolean valueSearchNonNull(Entry n, Object value) {
  203. // Check this node for the value
  204. if (value.equals(n.value))
  205. return true;
  206. // Check left and right subtrees for value
  207. return (n.left != null && valueSearchNonNull(n.left, value)) ||
  208. (n.right != null && valueSearchNonNull(n.right, value));
  209. }
  210. /**
  211. * Returns the value to which this map maps the specified key. Returns
  212. * <tt>null</tt> if the map contains no mapping for this key. A return
  213. * value of <tt>null</tt> does not <i>necessarily</i> indicate that the
  214. * map contains no mapping for the key; it's also possible that the map
  215. * explicitly maps the key to <tt>null</tt>. The <tt>containsKey</tt>
  216. * operation may be used to distinguish these two cases.
  217. *
  218. * @param key key whose associated value is to be returned.
  219. * @return the value to which this map maps the specified key, or
  220. * <tt>null</tt> if the map contains no mapping for the key.
  221. * @throws ClassCastException key cannot be compared with the keys
  222. * currently in the map.
  223. * @throws NullPointerException key is <tt>null</tt> and this map uses
  224. * natural ordering, or its comparator does not tolerate
  225. * <tt>null</tt> keys.
  226. *
  227. * @see #containsKey(Object)
  228. */
  229. public Object get(Object key) {
  230. Entry p = getEntry(key);
  231. return (p==null ? null : p.value);
  232. }
  233. /**
  234. * Returns the comparator used to order this map, or <tt>null</tt> if this
  235. * map uses its keys' natural order.
  236. *
  237. * @return the comparator associated with this sorted map, or
  238. * <tt>null</tt> if it uses its keys' natural sort method.
  239. */
  240. public Comparator comparator() {
  241. return comparator;
  242. }
  243. /**
  244. * Returns the first (lowest) key currently in this sorted map.
  245. *
  246. * @return the first (lowest) key currently in this sorted map.
  247. * @throws NoSuchElementException Map is empty.
  248. */
  249. public Object firstKey() {
  250. return key(firstEntry());
  251. }
  252. /**
  253. * Returns the last (highest) key currently in this sorted map.
  254. *
  255. * @return the last (highest) key currently in this sorted map.
  256. * @throws NoSuchElementException Map is empty.
  257. */
  258. public Object lastKey() {
  259. return key(lastEntry());
  260. }
  261. /**
  262. * Copies all of the mappings from the specified map to this map. These
  263. * mappings replace any mappings that this map had for any of the keys
  264. * currently in the specified map.
  265. *
  266. * @param map mappings to be stored in this map.
  267. * @throws ClassCastException class of a key or value in the specified
  268. * map prevents it from being stored in this map.
  269. *
  270. * @throws NullPointerException this map does not permit <tt>null</tt>
  271. * keys and a specified key is <tt>null</tt>.
  272. */
  273. public void putAll(Map map) {
  274. int mapSize = map.size();
  275. if (size==0 && mapSize!=0 && map instanceof SortedMap) {
  276. Comparator c = ((SortedMap)map).comparator();
  277. if (c == comparator || (c != null && c.equals(comparator))) {
  278. ++modCount;
  279. try {
  280. buildFromSorted(mapSize, map.entrySet().iterator(),
  281. null, null);
  282. } catch (java.io.IOException cannotHappen) {
  283. } catch (ClassNotFoundException cannotHappen) {
  284. }
  285. return;
  286. }
  287. }
  288. super.putAll(map);
  289. }
  290. /**
  291. * Returns this map's entry for the given key, or <tt>null</tt> if the map
  292. * does not contain an entry for the key.
  293. *
  294. * @return this map's entry for the given key, or <tt>null</tt> if the map
  295. * does not contain an entry for the key.
  296. * @throws ClassCastException if the key cannot be compared with the keys
  297. * currently in the map.
  298. * @throws NullPointerException key is <tt>null</tt> and this map uses
  299. * natural order, or its comparator does not tolerate *
  300. * <tt>null</tt> keys.
  301. */
  302. private Entry getEntry(Object key) {
  303. Entry p = root;
  304. while (p != null) {
  305. int cmp = compare(key,p.key);
  306. if (cmp == 0)
  307. return p;
  308. else if (cmp < 0)
  309. p = p.left;
  310. else
  311. p = p.right;
  312. }
  313. return null;
  314. }
  315. /**
  316. * Gets the entry corresponding to the specified key; if no such entry
  317. * exists, returns the entry for the least key greater than the specified
  318. * key; if no such entry exists (i.e., the greatest key in the Tree is less
  319. * than the specified key), returns <tt>null</tt>.
  320. */
  321. private Entry getCeilEntry(Object key) {
  322. Entry p = root;
  323. if (p==null)
  324. return null;
  325. while (true) {
  326. int cmp = compare(key, p.key);
  327. if (cmp == 0) {
  328. return p;
  329. } else if (cmp < 0) {
  330. if (p.left != null)
  331. p = p.left;
  332. else
  333. return p;
  334. } else {
  335. if (p.right != null) {
  336. p = p.right;
  337. } else {
  338. Entry parent = p.parent;
  339. Entry ch = p;
  340. while (parent != null && ch == parent.right) {
  341. ch = parent;
  342. parent = parent.parent;
  343. }
  344. return parent;
  345. }
  346. }
  347. }
  348. }
  349. /**
  350. * Returns the entry for the greatest key less than the specified key; if
  351. * no such entry exists (i.e., the least key in the Tree is greater than
  352. * the specified key), returns <tt>null</tt>.
  353. */
  354. private Entry getPrecedingEntry(Object key) {
  355. Entry p = root;
  356. if (p==null)
  357. return null;
  358. while (true) {
  359. int cmp = compare(key, p.key);
  360. if (cmp > 0) {
  361. if (p.right != null)
  362. p = p.right;
  363. else
  364. return p;
  365. } else {
  366. if (p.left != null) {
  367. p = p.left;
  368. } else {
  369. Entry parent = p.parent;
  370. Entry ch = p;
  371. while (parent != null && ch == parent.left) {
  372. ch = parent;
  373. parent = parent.parent;
  374. }
  375. return parent;
  376. }
  377. }
  378. }
  379. }
  380. /**
  381. * Returns the key corresonding to the specified Entry. Throw
  382. * NoSuchElementException if the Entry is <tt>null</tt>.
  383. */
  384. private static Object key(Entry e) {
  385. if (e==null)
  386. throw new NoSuchElementException();
  387. return e.key;
  388. }
  389. /**
  390. * Associates the specified value with the specified key in this map.
  391. * If the map previously contained a mapping for this key, the old
  392. * value is replaced.
  393. *
  394. * @param key key with which the specified value is to be associated.
  395. * @param value value to be associated with the specified key.
  396. *
  397. * @return previous value associated with specified key, or <tt>null</tt>
  398. * if there was no mapping for key. A <tt>null</tt> return can
  399. * also indicate that the map previously associated <tt>null</tt>
  400. * with the specified key.
  401. * @throws ClassCastException key cannot be compared with the keys
  402. * currently in the map.
  403. * @throws NullPointerException key is <tt>null</tt> and this map uses
  404. * natural order, or its comparator does not tolerate
  405. * <tt>null</tt> keys.
  406. */
  407. public Object put(Object key, Object value) {
  408. Entry t = root;
  409. if (t == null) {
  410. incrementSize();
  411. root = new Entry(key, value, null);
  412. return null;
  413. }
  414. while (true) {
  415. int cmp = compare(key, t.key);
  416. if (cmp == 0) {
  417. return t.setValue(value);
  418. } else if (cmp < 0) {
  419. if (t.left != null) {
  420. t = t.left;
  421. } else {
  422. incrementSize();
  423. t.left = new Entry(key, value, t);
  424. fixAfterInsertion(t.left);
  425. return null;
  426. }
  427. } else { // cmp > 0
  428. if (t.right != null) {
  429. t = t.right;
  430. } else {
  431. incrementSize();
  432. t.right = new Entry(key, value, t);
  433. fixAfterInsertion(t.right);
  434. return null;
  435. }
  436. }
  437. }
  438. }
  439. /**
  440. * Removes the mapping for this key from this TreeMap if present.
  441. *
  442. * @return previous value associated with specified key, or <tt>null</tt>
  443. * if there was no mapping for key. A <tt>null</tt> return can
  444. * also indicate that the map previously associated
  445. * <tt>null</tt> with the specified key.
  446. *
  447. * @throws ClassCastException key cannot be compared with the keys
  448. * currently in the map.
  449. * @throws NullPointerException key is <tt>null</tt> and this map uses
  450. * natural order, or its comparator does not tolerate
  451. * <tt>null</tt> keys.
  452. */
  453. public Object remove(Object key) {
  454. Entry p = getEntry(key);
  455. if (p == null)
  456. return null;
  457. Object oldValue = p.value;
  458. deleteEntry(p);
  459. return oldValue;
  460. }
  461. /**
  462. * Removes all mappings from this TreeMap.
  463. */
  464. public void clear() {
  465. modCount++;
  466. size = 0;
  467. root = null;
  468. }
  469. /**
  470. * Returns a shallow copy of this <tt>TreeMap</tt> instance. (The keys and
  471. * values themselves are not cloned.)
  472. *
  473. * @return a shallow copy of this Map.
  474. */
  475. public Object clone() {
  476. TreeMap clone = null;
  477. try {
  478. clone = (TreeMap)super.clone();
  479. } catch (CloneNotSupportedException e) {
  480. throw new InternalError();
  481. }
  482. // Put clone into "virgin" state (except for comparator)
  483. clone.root = null;
  484. clone.size = 0;
  485. clone.modCount = 0;
  486. clone.keySet = clone.entrySet = null;
  487. clone.values = null;
  488. // Initialize clone with our mappings
  489. try {
  490. clone.buildFromSorted(size, entrySet().iterator(), null, null);
  491. } catch (java.io.IOException cannotHappen) {
  492. } catch (ClassNotFoundException cannotHappen) {
  493. }
  494. return clone;
  495. }
  496. // Views
  497. /**
  498. * These fields are initialized to contain an instance of the appropriate
  499. * view the first time this view is requested. The views are stateless,
  500. * so there's no reason to create more than one of each.
  501. */
  502. private transient Set keySet = null;
  503. private transient Set entrySet = null;
  504. private transient Collection values = null;
  505. /**
  506. * Returns a Set view of the keys contained in this map. The set's
  507. * iterator will return the keys in ascending order. The map is backed by
  508. * this <tt>TreeMap</tt> instance, so changes to this map are reflected in
  509. * the Set, and vice-versa. The Set supports element removal, which
  510. * removes the corresponding mapping from the map, via the
  511. * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt>,
  512. * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not support
  513. * the <tt>add</tt> or <tt>addAll</tt> operations.
  514. *
  515. * @return a set view of the keys contained in this TreeMap.
  516. */
  517. public Set keySet() {
  518. if (keySet == null) {
  519. keySet = new AbstractSet() {
  520. public java.util.Iterator iterator() {
  521. return new Iterator(KEYS);
  522. }
  523. public int size() {
  524. return TreeMap.this.size();
  525. }
  526. public boolean contains(Object o) {
  527. return containsKey(o);
  528. }
  529. public boolean remove(Object o) {
  530. int oldSize = size;
  531. TreeMap.this.remove(o);
  532. return size != oldSize;
  533. }
  534. public void clear() {
  535. TreeMap.this.clear();
  536. }
  537. };
  538. }
  539. return keySet;
  540. }
  541. /**
  542. * Returns a collection view of the values contained in this map. The
  543. * collection's iterator will return the values in the order that their
  544. * corresponding keys appear in the tree. The collection is backed by
  545. * this <tt>TreeMap</tt> instance, so changes to this map are reflected in
  546. * the collection, and vice-versa. The collection supports element
  547. * removal, which removes the corresponding mapping from the map through
  548. * the <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
  549. * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
  550. * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
  551. *
  552. * @return a collection view of the values contained in this map.
  553. */
  554. public Collection values() {
  555. if (values == null) {
  556. values = new AbstractCollection() {
  557. public java.util.Iterator iterator() {
  558. return new Iterator(VALUES);
  559. }
  560. public int size() {
  561. return TreeMap.this.size();
  562. }
  563. public boolean contains(Object o) {
  564. for (Entry e = firstEntry(); e != null; e = successor(e))
  565. if (valEquals(e.getValue(), o))
  566. return true;
  567. return false;
  568. }
  569. public boolean remove(Object o) {
  570. for (Entry e = firstEntry(); e != null; e = successor(e)) {
  571. if (valEquals(e.getValue(), o)) {
  572. deleteEntry(e);
  573. return true;
  574. }
  575. }
  576. return false;
  577. }
  578. public void clear() {
  579. TreeMap.this.clear();
  580. }
  581. };
  582. }
  583. return values;
  584. }
  585. /**
  586. * Returns a set view of the mappings contained in this map. The set's
  587. * iterator returns the mappings in ascending key order. Each element in
  588. * the returned set is a <tt>Map.Entry</tt>. The set is backed by this
  589. * map, so changes to this map are reflected in the set, and vice-versa.
  590. * The set supports element removal, which removes the corresponding
  591. * mapping from the TreeMap, through the <tt>Iterator.remove</tt>,
  592. * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
  593. * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
  594. * <tt>addAll</tt> operations.
  595. *
  596. * @return a set view of the mappings contained in this map.
  597. * @see Map.Entry
  598. */
  599. public Set entrySet() {
  600. if (entrySet == null) {
  601. entrySet = new AbstractSet() {
  602. public java.util.Iterator iterator() {
  603. return new Iterator(ENTRIES);
  604. }
  605. public boolean contains(Object o) {
  606. if (!(o instanceof Map.Entry))
  607. return false;
  608. Map.Entry entry = (Map.Entry)o;
  609. Object value = entry.getValue();
  610. Entry p = getEntry(entry.getKey());
  611. return p != null && valEquals(p.getValue(), value);
  612. }
  613. public boolean remove(Object o) {
  614. if (!(o instanceof Map.Entry))
  615. return false;
  616. Map.Entry entry = (Map.Entry)o;
  617. Object value = entry.getValue();
  618. Entry p = getEntry(entry.getKey());
  619. if (p != null && valEquals(p.getValue(), value)) {
  620. deleteEntry(p);
  621. return true;
  622. }
  623. return false;
  624. }
  625. public int size() {
  626. return TreeMap.this.size();
  627. }
  628. public void clear() {
  629. TreeMap.this.clear();
  630. }
  631. };
  632. }
  633. return entrySet;
  634. }
  635. /**
  636. * Returns a view of the portion of this map whose keys range from
  637. * <tt>fromKey</tt>, inclusive, to <tt>toKey</tt>, exclusive. (If
  638. * <tt>fromKey</tt> and <tt>toKey</tt> are equal, the returned sorted map
  639. * is empty.) The returned sorted map is backed by this map, so changes
  640. * in the returned sorted map are reflected in this map, and vice-versa.
  641. * The returned sorted map supports all optional map operations.<p>
  642. *
  643. * The sorted map returned by this method will throw an
  644. * <tt>IllegalArgumentException</tt> if the user attempts to insert a key
  645. * less than <tt>fromKey</tt> or greater than or equal to
  646. * <tt>toKey</tt>.<p>
  647. *
  648. * Note: this method always returns a <i>half-open range</i> (which
  649. * includes its low endpoint but not its high endpoint). If you need a
  650. * <i>closed range</i> (which includes both endpoints), and the key type
  651. * allows for calculation of the successor a given key, merely request the
  652. * subrange from <tt>lowEndpoint</tt> to <tt>successor(highEndpoint)</tt>.
  653. * For example, suppose that <tt>m</tt> is a sorted map whose keys are
  654. * strings. The following idiom obtains a view containing all of the
  655. * key-value mappings in <tt>m</tt> whose keys are between <tt>low</tt>
  656. * and <tt>high</tt>, inclusive:
  657. * <pre> SortedMap sub = m.submap(low, high+"\0");</pre>
  658. * A similar technique can be used to generate an <i>open range</i> (which
  659. * contains neither endpoint). The following idiom obtains a view
  660. * containing all of the key-value mappings in <tt>m</tt> whose keys are
  661. * between <tt>low</tt> and <tt>high</tt>, exclusive:
  662. * <pre> SortedMap sub = m.subMap(low+"\0", high);</pre>
  663. *
  664. * @param fromKey low endpoint (inclusive) of the subMap.
  665. * @param toKey high endpoint (exclusive) of the subMap.
  666. *
  667. * @return a view of the portion of this map whose keys range from
  668. * <tt>fromKey</tt>, inclusive, to <tt>toKey</tt>, exclusive.
  669. *
  670. * @throws ClassCastException if <tt>fromKey</tt> and <tt>toKey</tt>
  671. * cannot be compared to one another using this map's comparator
  672. * (or, if the map has no comparator, using natural ordering).
  673. * @throws IllegalArgumentException if <tt>fromKey</tt> is greater than
  674. * <tt>toKey</tt>.
  675. * @throws NullPointerException if <tt>fromKey</tt> or <tt>toKey</tt> is
  676. * <tt>null</tt> and this map uses natural order, or its
  677. * comparator does not tolerate <tt>null</tt> keys.
  678. */
  679. public SortedMap subMap(Object fromKey, Object toKey) {
  680. return new SubMap(fromKey, toKey);
  681. }
  682. /**
  683. * Returns a view of the portion of this map whose keys are strictly less
  684. * than <tt>toKey</tt>. The returned sorted map is backed by this map, so
  685. * changes in the returned sorted map are reflected in this map, and
  686. * vice-versa. The returned sorted map supports all optional map
  687. * operations.<p>
  688. *
  689. * The sorted map returned by this method will throw an
  690. * <tt>IllegalArgumentException</tt> if the user attempts to insert a key
  691. * greater than or equal to <tt>toKey</tt>.<p>
  692. *
  693. * Note: this method always returns a view that does not contain its
  694. * (high) endpoint. If you need a view that does contain this endpoint,
  695. * and the key type allows for calculation of the successor a given key,
  696. * merely request a headMap bounded by <tt>successor(highEndpoint)</tt>.
  697. * For example, suppose that suppose that <tt>m</tt> is a sorted map whose
  698. * keys are strings. The following idiom obtains a view containing all of
  699. * the key-value mappings in <tt>m</tt> whose keys are less than or equal
  700. * to <tt>high</tt>:
  701. * <pre>
  702. * SortedMap head = m.headMap(high+"\0");
  703. * </pre>
  704. *
  705. * @param toKey high endpoint (exclusive) of the headMap.
  706. * @return a view of the portion of this map whose keys are strictly
  707. * less than <tt>toKey</tt>.
  708. *
  709. * @throws ClassCastException if <tt>toKey</tt> is not compatible
  710. * with this map's comparator (or, if the map has no comparator,
  711. * if <tt>toKey</tt> does not implement <tt>Comparable</tt>).
  712. * @throws IllegalArgumentException if this map is itself a subMap,
  713. * headMap, or tailMap, and <tt>toKey</tt> is not within the
  714. * specified range of the subMap, headMap, or tailMap.
  715. * @throws NullPointerException if <tt>toKey</tt> is <tt>null</tt> and
  716. * this map uses natural order, or its comparator does not
  717. * tolerate <tt>null</tt> keys.
  718. */
  719. public SortedMap headMap(Object toKey) {
  720. return new SubMap(toKey, true);
  721. }
  722. /**
  723. * Returns a view of the portion of this map whose keys are greater than
  724. * or equal to <tt>fromKey</tt>. The returned sorted map is backed by
  725. * this map, so changes in the returned sorted map are reflected in this
  726. * map, and vice-versa. The returned sorted map supports all optional map
  727. * operations.<p>
  728. *
  729. * The sorted map returned by this method will throw an
  730. * <tt>IllegalArgumentException</tt> if the user attempts to insert a key
  731. * less than <tt>fromKey</tt>.<p>
  732. *
  733. * Note: this method always returns a view that contains its (low)
  734. * endpoint. If you need a view that does not contain this endpoint, and
  735. * the element type allows for calculation of the successor a given value,
  736. * merely request a tailMap bounded by <tt>successor(lowEndpoint)</tt>.
  737. * For For example, suppose that suppose that <tt>m</tt> is a sorted map
  738. * whose keys are strings. The following idiom obtains a view containing
  739. * all of the key-value mappings in <tt>m</tt> whose keys are strictly
  740. * greater than <tt>low</tt>: <pre>
  741. * SortedMap tail = m.tailMap(low+"\0");
  742. * </pre>
  743. *
  744. * @param fromKey low endpoint (inclusive) of the tailMap.
  745. * @return a view of the portion of this map whose keys are greater
  746. * than or equal to <tt>fromKey</tt>.
  747. * @throws ClassCastException if <tt>fromKey</tt> is not compatible
  748. * with this map's comparator (or, if the map has no comparator,
  749. * if <tt>fromKey</tt> does not implement <tt>Comparable</tt>).
  750. * @throws IllegalArgumentException if this map is itself a subMap,
  751. * headMap, or tailMap, and <tt>fromKey</tt> is not within the
  752. * specified range of the subMap, headMap, or tailMap.
  753. * @throws NullPointerException if <tt>fromKey</tt> is <tt>null</tt> and
  754. * this map uses natural order, or its comparator does not
  755. * tolerate <tt>null</tt> keys.
  756. */
  757. public SortedMap tailMap(Object fromKey) {
  758. return new SubMap(fromKey, false);
  759. }
  760. private class SubMap extends AbstractMap
  761. implements SortedMap, java.io.Serializable {
  762. private static final long serialVersionUID = -6520786458950516097L;
  763. /**
  764. * fromKey is significant only if fromStart is false. Similarly,
  765. * toKey is significant only if toStart is false.
  766. */
  767. private boolean fromStart = false, toEnd = false;
  768. private Object fromKey, toKey;
  769. SubMap(Object fromKey, Object toKey) {
  770. if (compare(fromKey, toKey) > 0)
  771. throw new IllegalArgumentException("fromKey > toKey");
  772. this.fromKey = fromKey;
  773. this.toKey = toKey;
  774. }
  775. SubMap(Object key, boolean headMap) {
  776. compare(key, key); // Type-check key
  777. if (headMap) {
  778. fromStart = true;
  779. toKey = key;
  780. } else {
  781. toEnd = true;
  782. fromKey = key;
  783. }
  784. }
  785. SubMap(boolean fromStart, Object fromKey, boolean toEnd, Object toKey){
  786. this.fromStart = fromStart;
  787. this.fromKey= fromKey;
  788. this.toEnd = toEnd;
  789. this.toKey = toKey;
  790. }
  791. public boolean isEmpty() {
  792. return entrySet.isEmpty();
  793. }
  794. public boolean containsKey(Object key) {
  795. return inRange(key) && TreeMap.this.containsKey(key);
  796. }
  797. public Object get(Object key) {
  798. if (!inRange(key))
  799. return null;
  800. return TreeMap.this.get(key);
  801. }
  802. public Object put(Object key, Object value) {
  803. if (!inRange(key))
  804. throw new IllegalArgumentException("key out of range");
  805. return TreeMap.this.put(key, value);
  806. }
  807. public Comparator comparator() {
  808. return comparator;
  809. }
  810. public Object firstKey() {
  811. Object first = key(fromStart ? firstEntry():getCeilEntry(fromKey));
  812. if (!toEnd && compare(first, toKey) >= 0)
  813. throw(new NoSuchElementException());
  814. return first;
  815. }
  816. public Object lastKey() {
  817. Object last = key(toEnd ? lastEntry() : getPrecedingEntry(toKey));
  818. if (!fromStart && compare(last, fromKey) < 0)
  819. throw(new NoSuchElementException());
  820. return last;
  821. }
  822. private transient Set entrySet = new EntrySetView();
  823. public Set entrySet() {
  824. return entrySet;
  825. }
  826. private class EntrySetView extends AbstractSet {
  827. private transient int size = -1, sizeModCount;
  828. public int size() {
  829. if (size == -1 || sizeModCount != TreeMap.this.modCount) {
  830. size = 0; sizeModCount = TreeMap.this.modCount;
  831. java.util.Iterator i = iterator();
  832. while (i.hasNext()) {
  833. size++;
  834. i.next();
  835. }
  836. }
  837. return size;
  838. }
  839. public boolean isEmpty() {
  840. return !iterator().hasNext();
  841. }
  842. public boolean contains(Object o) {
  843. if (!(o instanceof Map.Entry))
  844. return false;
  845. Map.Entry entry = (Map.Entry)o;
  846. Object key = entry.getKey();
  847. if (!inRange(key))
  848. return false;
  849. TreeMap.Entry node = getEntry(key);
  850. return node != null &&
  851. valEquals(node.getValue(), entry.getValue());
  852. }
  853. public boolean remove(Object o) {
  854. if (!(o instanceof Map.Entry))
  855. return false;
  856. Map.Entry entry = (Map.Entry)o;
  857. Object key = entry.getKey();
  858. if (!inRange(key))
  859. return false;
  860. TreeMap.Entry node = getEntry(key);
  861. if (node!=null && valEquals(node.getValue(),entry.getValue())){
  862. deleteEntry(node);
  863. return true;
  864. }
  865. return false;
  866. }
  867. public java.util.Iterator iterator() {
  868. return new Iterator(
  869. (fromStart ? firstEntry() : getCeilEntry(fromKey)),
  870. (toEnd ? null : getCeilEntry(toKey)));
  871. }
  872. }
  873. public SortedMap subMap(Object fromKey, Object toKey) {
  874. if (!inRange2(fromKey))
  875. throw new IllegalArgumentException("fromKey out of range");
  876. if (!inRange2(toKey))
  877. throw new IllegalArgumentException("toKey out of range");
  878. return new SubMap(fromKey, toKey);
  879. }
  880. public SortedMap headMap(Object toKey) {
  881. if (!inRange2(toKey))
  882. throw new IllegalArgumentException("toKey out of range");
  883. return new SubMap(fromStart, fromKey, false, toKey);
  884. }
  885. public SortedMap tailMap(Object fromKey) {
  886. if (!inRange2(fromKey))
  887. throw new IllegalArgumentException("fromKey out of range");
  888. return new SubMap(false, fromKey, toEnd, toKey);
  889. }
  890. private boolean inRange(Object key) {
  891. return (fromStart || compare(key, fromKey) >= 0) &&
  892. (toEnd || compare(key, toKey) < 0);
  893. }
  894. // This form allows the high endpoint (as well as all legit keys)
  895. private boolean inRange2(Object key) {
  896. return (fromStart || compare(key, fromKey) >= 0) &&
  897. (toEnd || compare(key, toKey) <= 0);
  898. }
  899. }
  900. // Types of Iterators
  901. private static final int KEYS = 0;
  902. private static final int VALUES = 1;
  903. private static final int ENTRIES = 2;
  904. /**
  905. * TreeMap Iterator.
  906. */
  907. private class Iterator implements java.util.Iterator {
  908. private int type;
  909. private int expectedModCount = TreeMap.this.modCount;
  910. private Entry lastReturned = null;
  911. private Entry next;
  912. private Entry firstExcluded = null;
  913. Iterator(int type) {
  914. this.type = type;
  915. next = firstEntry();
  916. }
  917. Iterator(Entry first, Entry firstExcluded) {
  918. type = ENTRIES;
  919. next = first;
  920. this.firstExcluded = firstExcluded;
  921. }
  922. public boolean hasNext() {
  923. return next != firstExcluded;
  924. }
  925. public Object next() {
  926. if (next == firstExcluded)
  927. throw new NoSuchElementException();
  928. if (modCount != expectedModCount)
  929. throw new ConcurrentModificationException();
  930. lastReturned = next;
  931. next = successor(next);
  932. return (type == KEYS ? lastReturned.key :
  933. (type == VALUES ? lastReturned.value : lastReturned));
  934. }
  935. public void remove() {
  936. if (lastReturned == null)
  937. throw new IllegalStateException();
  938. if (modCount != expectedModCount)
  939. throw new ConcurrentModificationException();
  940. deleteEntry(lastReturned);
  941. expectedModCount++;
  942. lastReturned = null;
  943. }
  944. }
  945. /**
  946. * Compares two keys using the correct comparison method for this TreeMap.
  947. */
  948. private int compare(Object k1, Object k2) {
  949. return (comparator==null ? ((Comparable)k1).compareTo(k2)
  950. : comparator.compare(k1, k2));
  951. }
  952. /**
  953. * Test two values for equality. Differs from o1.equals(o2) only in
  954. * that it copes with with <tt>null</tt> o1 properly.
  955. */
  956. private static boolean valEquals(Object o1, Object o2) {
  957. return (o1==null ? o2==null : o1.equals(o2));
  958. }
  959. private static final boolean RED = false;
  960. private static final boolean BLACK = true;
  961. /**
  962. * Node in the Tree. Doubles as a means to pass key-value pairs back to
  963. * user (see Map.Entry).
  964. */
  965. static class Entry implements Map.Entry {
  966. Object key;
  967. Object value;
  968. Entry left = null;
  969. Entry right = null;
  970. Entry parent;
  971. boolean color = BLACK;
  972. /**
  973. * Make a new cell with given key, value, and parent, and with <tt>null</tt>
  974. * child links, and BLACK color.
  975. */
  976. Entry(Object key, Object value, Entry parent) {
  977. this.key = key;
  978. this.value = value;
  979. this.parent = parent;
  980. }
  981. /**
  982. * Returns the key.
  983. *
  984. * @return the key.
  985. */
  986. public Object getKey() {
  987. return key;
  988. }
  989. /**
  990. * Returns the value associated with the key.
  991. *
  992. * @return the value associated with the key.
  993. */
  994. public Object getValue() {
  995. return value;
  996. }
  997. /**
  998. * Replaces the value currently associated with the key with the given
  999. * value.
  1000. *
  1001. * @return the value associated with the key before this method was
  1002. * called.
  1003. */
  1004. public Object setValue(Object value) {
  1005. Object oldValue = this.value;
  1006. this.value = value;
  1007. return oldValue;
  1008. }
  1009. public boolean equals(Object o) {
  1010. if (!(o instanceof Map.Entry))
  1011. return false;
  1012. Map.Entry e = (Map.Entry)o;
  1013. return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
  1014. }
  1015. public int hashCode() {
  1016. int keyHash = (key==null ? 0 : key.hashCode());
  1017. int valueHash = (value==null ? 0 : value.hashCode());
  1018. return keyHash ^ valueHash;
  1019. }
  1020. public String toString() {
  1021. return key + "=" + value;
  1022. }
  1023. }
  1024. /**
  1025. * Returns the first Entry in the TreeMap (according to the TreeMap's
  1026. * key-sort function). Returns null if the TreeMap is empty.
  1027. */
  1028. private Entry firstEntry() {
  1029. Entry p = root;
  1030. if (p != null)
  1031. while (p.left != null)
  1032. p = p.left;
  1033. return p;
  1034. }
  1035. /**
  1036. * Returns the last Entry in the TreeMap (according to the TreeMap's
  1037. * key-sort function). Returns null if the TreeMap is empty.
  1038. */
  1039. private Entry lastEntry() {
  1040. Entry p = root;
  1041. if (p != null)
  1042. while (p.right != null)
  1043. p = p.right;
  1044. return p;
  1045. }
  1046. /**
  1047. * Returns the successor of the specified Entry, or null if no such.
  1048. */
  1049. private Entry successor(Entry t) {
  1050. if (t == null)
  1051. return null;
  1052. else if (t.right != null) {
  1053. Entry p = t.right;
  1054. while (p.left != null)
  1055. p = p.left;
  1056. return p;
  1057. } else {
  1058. Entry p = t.parent;
  1059. Entry ch = t;
  1060. while (p != null && ch == p.right) {
  1061. ch = p;
  1062. p = p.parent;
  1063. }
  1064. return p;
  1065. }
  1066. }
  1067. /**
  1068. * Balancing operations.
  1069. *
  1070. * Implementations of rebalancings during insertion and deletion are
  1071. * slightly different than the CLR version. Rather than using dummy
  1072. * nilnodes, we use a set of accessors that deal properly with null. They
  1073. * are used to avoid messiness surrounding nullness checks in the main
  1074. * algorithms.
  1075. */
  1076. private static boolean colorOf(Entry p) {
  1077. return (p == null ? BLACK : p.color);
  1078. }
  1079. private static Entry parentOf(Entry p) {
  1080. return (p == null ? null: p.parent);
  1081. }
  1082. private static void setColor(Entry p, boolean c) {
  1083. if (p != null) p.color = c;
  1084. }
  1085. private static Entry leftOf(Entry p) {
  1086. return (p == null)? null: p.left;
  1087. }
  1088. private static Entry rightOf(Entry p) {
  1089. return (p == null)? null: p.right;
  1090. }
  1091. /** From CLR **/
  1092. private void rotateLeft(Entry p) {
  1093. Entry r = p.right;
  1094. p.right = r.left;
  1095. if (r.left != null)
  1096. r.left.parent = p;
  1097. r.parent = p.parent;
  1098. if (p.parent == null)
  1099. root = r;
  1100. else if (p.parent.left == p)
  1101. p.parent.left = r;
  1102. else
  1103. p.parent.right = r;
  1104. r.left = p;
  1105. p.parent = r;
  1106. }
  1107. /** From CLR **/
  1108. private void rotateRight(Entry p) {
  1109. Entry l = p.left;
  1110. p.left = l.right;
  1111. if (l.right != null) l.right.parent = p;
  1112. l.parent = p.parent;
  1113. if (p.parent == null)
  1114. root = l;
  1115. else if (p.parent.right == p)
  1116. p.parent.right = l;
  1117. else p.parent.left = l;
  1118. l.right = p;
  1119. p.parent = l;
  1120. }
  1121. /** From CLR **/
  1122. private void fixAfterInsertion(Entry x) {
  1123. x.color = RED;
  1124. while (x != null && x != root && x.parent.color == RED) {
  1125. if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
  1126. Entry y = rightOf(parentOf(parentOf(x)));
  1127. if (colorOf(y) == RED) {
  1128. setColor(parentOf(x), BLACK);
  1129. setColor(y, BLACK);
  1130. setColor(parentOf(parentOf(x)), RED);
  1131. x = parentOf(parentOf(x));
  1132. } else {
  1133. if (x == rightOf(parentOf(x))) {
  1134. x = parentOf(x);
  1135. rotateLeft(x);
  1136. }
  1137. setColor(parentOf(x), BLACK);
  1138. setColor(parentOf(parentOf(x)), RED);
  1139. if (parentOf(parentOf(x)) != null)
  1140. rotateRight(parentOf(parentOf(x)));
  1141. }
  1142. } else {
  1143. Entry y = leftOf(parentOf(parentOf(x)));
  1144. if (colorOf(y) == RED) {
  1145. setColor(parentOf(x), BLACK);
  1146. setColor(y, BLACK);
  1147. setColor(parentOf(parentOf(x)), RED);
  1148. x = parentOf(parentOf(x));
  1149. } else {
  1150. if (x == leftOf(parentOf(x))) {
  1151. x = parentOf(x);
  1152. rotateRight(x);
  1153. }
  1154. setColor(parentOf(x), BLACK);
  1155. setColor(parentOf(parentOf(x)), RED);
  1156. if (parentOf(parentOf(x)) != null)
  1157. rotateLeft(parentOf(parentOf(x)));
  1158. }
  1159. }
  1160. }
  1161. root.color = BLACK;
  1162. }
  1163. /**
  1164. * Delete node p, and then rebalance the tree.
  1165. */
  1166. private void deleteEntry(Entry p) {
  1167. decrementSize();
  1168. // If strictly internal, first swap position with successor.
  1169. if (p.left != null && p.right != null) {
  1170. Entry s = successor(p);
  1171. swapPosition(s, p);
  1172. }
  1173. // Start fixup at replacement node, if it exists.
  1174. Entry replacement = (p.left != null ? p.left : p.right);
  1175. if (replacement != null) {
  1176. // Link replacement to parent
  1177. replacement.parent = p.parent;
  1178. if (p.parent == null)
  1179. root = replacement;
  1180. else if (p == p.parent.left)
  1181. p.parent.left = replacement;
  1182. else
  1183. p.parent.right = replacement;
  1184. // Null out links so they are OK to use by fixAfterDeletion.
  1185. p.left = p.right = p.parent = null;
  1186. // Fix replacement
  1187. if (p.color == BLACK)
  1188. fixAfterDeletion(replacement);
  1189. } else if (p.parent == null) { // return if we are the only node.
  1190. root = null;
  1191. } else { // No children. Use self as phantom replacement and unlink.
  1192. if (p.color == BLACK)
  1193. fixAfterDeletion(p);
  1194. if (p.parent != null) {
  1195. if (p == p.parent.left)
  1196. p.parent.left = null;
  1197. else if (p == p.parent.right)
  1198. p.parent.right = null;
  1199. p.parent = null;
  1200. }
  1201. }
  1202. }
  1203. /** From CLR **/
  1204. private void fixAfterDeletion(Entry x) {
  1205. while (x != root && colorOf(x) == BLACK) {
  1206. if (x == leftOf(parentOf(x))) {
  1207. Entry sib = rightOf(parentOf(x));
  1208. if (colorOf(sib) == RED) {
  1209. setColor(sib, BLACK);
  1210. setColor(parentOf(x), RED);
  1211. rotateLeft(parentOf(x));
  1212. sib = rightOf(parentOf(x));
  1213. }
  1214. if (colorOf(leftOf(sib)) == BLACK &&
  1215. colorOf(rightOf(sib)) == BLACK) {
  1216. setColor(sib, RED);
  1217. x = parentOf(x);
  1218. } else {
  1219. if (colorOf(rightOf(sib)) == BLACK) {
  1220. setColor(leftOf(sib), BLACK);
  1221. setColor(sib, RED);
  1222. rotateRight(sib);
  1223. sib = rightOf(parentOf(x));
  1224. }
  1225. setColor(sib, colorOf(parentOf(x)));
  1226. setColor(parentOf(x), BLACK);
  1227. setColor(rightOf(sib), BLACK);
  1228. rotateLeft(parentOf(x));
  1229. x = root;
  1230. }
  1231. } else { // symmetric
  1232. Entry sib = leftOf(parentOf(x));
  1233. if (colorOf(sib) == RED) {
  1234. setColor(sib, BLACK);
  1235. setColor(parentOf(x), RED);
  1236. rotateRight(parentOf(x));
  1237. sib = leftOf(parentOf(x));
  1238. }
  1239. if (colorOf(rightOf(sib)) == BLACK &&
  1240. colorOf(leftOf(sib)) == BLACK) {
  1241. setColor(sib, RED);
  1242. x = parentOf(x);
  1243. } else {
  1244. if (colorOf(leftOf(sib)) == BLACK) {
  1245. setColor(rightOf(sib), BLACK);
  1246. setColor(sib, RED);
  1247. rotateLeft(sib);
  1248. sib = leftOf(parentOf(x));
  1249. }
  1250. setColor(sib, colorOf(parentOf(x)));
  1251. setColor(parentOf(x), BLACK);
  1252. setColor(leftOf(sib), BLACK);
  1253. rotateRight(parentOf(x));
  1254. x = root;
  1255. }
  1256. }
  1257. }
  1258. setColor(x, BLACK);
  1259. }
  1260. /**
  1261. * Swap the linkages of two nodes in a tree.
  1262. */
  1263. private void swapPosition(Entry x, Entry y) {
  1264. // Save initial values.
  1265. Entry px = x.parent, lx = x.left, rx = x.right;
  1266. Entry py = y.parent, ly = y.left, ry = y.right;
  1267. boolean xWasLeftChild = px != null && x == px.left;
  1268. boolean yWasLeftChild = py != null && y == py.left;
  1269. // Swap, handling special cases of one being the other's parent.
  1270. if (x == py) { // x was y's parent
  1271. x.parent = y;
  1272. if (yWasLeftChild) {
  1273. y.left = x;
  1274. y.right = rx;
  1275. } else {
  1276. y.right = x;
  1277. y.left = lx;
  1278. }
  1279. } else {
  1280. x.parent = py;
  1281. if (py != null) {
  1282. if (yWasLeftChild)
  1283. py.left = x;
  1284. else
  1285. py.right = x;
  1286. }
  1287. y.left = lx;
  1288. y.right = rx;
  1289. }
  1290. if (y == px) { // y was x's parent
  1291. y.parent = x;
  1292. if (xWasLeftChild) {
  1293. x.left = y;
  1294. x.right = ry;
  1295. } else {
  1296. x.right = y;
  1297. x.left = ly;
  1298. }
  1299. } else {
  1300. y.parent = px;
  1301. if (px != null) {
  1302. if (xWasLeftChild)
  1303. px.left = y;
  1304. else
  1305. px.right = y;
  1306. }
  1307. x.left = ly;
  1308. x.right = ry;
  1309. }
  1310. // Fix children's parent pointers
  1311. if (x.left != null)
  1312. x.left.parent = x;
  1313. if (x.right != null)
  1314. x.right.parent = x;
  1315. if (y.left != null)
  1316. y.left.parent = y;
  1317. if (y.right != null)
  1318. y.right.parent = y;
  1319. // Swap colors
  1320. boolean c = x.color;
  1321. x.color = y.color;
  1322. y.color = c;
  1323. // Check if root changed
  1324. if (root == x)
  1325. root = y;
  1326. else if (root == y)
  1327. root = x;
  1328. }
  1329. private static final long serialVersionUID = 919286545866124006L;
  1330. /**
  1331. * Save the state of the <tt>TreeMap</tt> instance to a stream (i.e.,
  1332. * serialize it).
  1333. *
  1334. * @serialData The <i>size</i> of the TreeMap (the number of key-value
  1335. * mappings) is emitted (int), followed by the key (Object)
  1336. * and value (Object) for each key-value mapping represented
  1337. * by the TreeMap. The key-value mappings are emitted in
  1338. * key-order (as determined by the TreeMap's Comparator,
  1339. * or by the keys' natural ordering if the TreeMap has no
  1340. * Comparator).
  1341. */
  1342. private void writeObject(java.io.ObjectOutputStream s)
  1343. throws java.io.IOException {
  1344. // Write out the Comparator and any hidden stuff
  1345. s.defaultWriteObject();
  1346. // Write out size (number of Mappings)
  1347. s.writeInt(size);
  1348. // Write out keys and values (alternating)
  1349. for (java.util.Iterator i = entrySet().iterator(); i.hasNext(); ) {
  1350. Entry e = (Entry)i.next();
  1351. s.writeObject(e.key);
  1352. s.writeObject(e.value);
  1353. }
  1354. }
  1355. /**
  1356. * Reconstitute the <tt>TreeMap</tt> instance from a stream (i.e.,
  1357. * deserialize it).
  1358. */
  1359. private void readObject(final java.io.ObjectInputStream s)
  1360. throws java.io.IOException, ClassNotFoundException {
  1361. // Read in the Comparator and any hidden stuff
  1362. s.defaultReadObject();
  1363. // Read in size
  1364. int size = s.readInt();
  1365. buildFromSorted(size, null, s, null);
  1366. }
  1367. /** Intended to be called only from TreeSet.readObject **/
  1368. void readTreeSet(int size, java.io.ObjectInputStream s, Object defaultVal)
  1369. throws java.io.IOException, ClassNotFoundException {
  1370. buildFromSorted(size, null, s, defaultVal);
  1371. }
  1372. /** Intended to be called only from TreeSet.addAll **/
  1373. void addAllForTreeSet(SortedSet set, Object defaultVal) {
  1374. try {
  1375. buildFromSorted(set.size(), set.iterator(), null, defaultVal);
  1376. } catch (java.io.IOException cannotHappen) {
  1377. } catch (ClassNotFoundException cannotHappen) {
  1378. }
  1379. }
  1380. /**
  1381. * Linear time tree building algorithm from sorted data. Can accept keys
  1382. * and/or values from iterator or stream. This leads to too many
  1383. * parameters, but seems better than alternatives. The four formats
  1384. * that this method accepts are:
  1385. *
  1386. * 1) An iterator of Map.Entries. (it != null, defaultVal == null).
  1387. * 2) An iterator of keys. (it != null, defaultVal != null).
  1388. * 3) A stream of alternating serialized keys and values.
  1389. * (it == null, defaultVal == null).
  1390. * 4) A stream of serialized keys. (it == null, defaultVal != null).
  1391. *
  1392. * It is assumed that the comparator of the TreeMap is already set prior
  1393. * to calling this method.
  1394. *
  1395. * @param size the number of keys (or key-value pairs) to be read from
  1396. * the iterator or stream.
  1397. * @param it If non-null, new entries are created from entries
  1398. * or keys read from this iterator.
  1399. * @param it If non-null, new entries are created from keys and
  1400. * possibly values read from this stream in serialized form.
  1401. * Exactly one of it and str should be non-null.
  1402. * @param defaultVal if non-null, this default value is used for
  1403. * each value in the map. If null, each value is read from
  1404. * iterator or stream, as described above.
  1405. * @throws IOException propagated from stream reads. This cannot
  1406. * occur if str is null.
  1407. * @throws ClassNotFoundException propagated from readObject.
  1408. * This cannot occur if str is null.
  1409. */
  1410. private void buildFromSorted(int size, java.util.Iterator it,
  1411. java.io.ObjectInputStream str,
  1412. Object defaultVal)
  1413. throws java.io.IOException, ClassNotFoundException {
  1414. this.size = size;
  1415. root = buildFromSorted(0, 0, size-1, computeRedLevel(size),
  1416. it, str, defaultVal);
  1417. }
  1418. /**
  1419. * Recursive "helper method" that does the real work of the
  1420. * of the previous method. Identically named parameters have
  1421. * identical definitions. Additional parameters are documented below.
  1422. * It is assumed that the comparator and size fields of the TreeMap are
  1423. * already set prior to calling this method. (It ignores both fields.)
  1424. *
  1425. * @param level the current level of tree. Initial call should be 0.
  1426. * @param lo the first element index of this subtree. Initial should be 0.
  1427. * @param hi the last element index of this subtree. Initial should be
  1428. * size-1.
  1429. * @param redLevel the level at which nodes should be red.
  1430. * Must be equal to computeRedLevel for tree of this size.
  1431. */
  1432. private static Entry buildFromSorted(int level, int lo, int hi,
  1433. int redLevel,
  1434. java.util.Iterator it,
  1435. java.io.ObjectInputStream str,
  1436. Object defaultVal)
  1437. throws java.io.IOException, ClassNotFoundException {
  1438. /*
  1439. * Strategy: The root is the middlemost element. To get to it, we
  1440. * have to first recursively construct the entire left subtree,
  1441. * so as to grab all of its elements. We can then proceed with right
  1442. * subtree.
  1443. *
  1444. * The lo and hi arguments are the minimum and maximum
  1445. * indices to pull out of the iterator or stream for current subtree.
  1446. * They are not actually indexed, we just proceed sequentially,
  1447. * ensuring that items are extracted in corresponding order.
  1448. */
  1449. if (hi < lo) return null;
  1450. int mid = (lo + hi) / 2;
  1451. Entry left = null;
  1452. if (lo < mid)
  1453. left = buildFromSorted(level+1, lo, mid - 1, redLevel,
  1454. it, str, defaultVal);
  1455. // extract key and/or value from iterator or stream
  1456. Object key;
  1457. Object value;
  1458. if (it != null) { // use iterator
  1459. if (defaultVal==null) {
  1460. Map.Entry entry = (Map.Entry) it.next();
  1461. key = entry.getKey();
  1462. value = entry.getValue();
  1463. } else {
  1464. key = it.next();
  1465. value = defaultVal;
  1466. }
  1467. } else { // use stream
  1468. key = str.readObject();
  1469. value = (defaultVal != null ? defaultVal : str.readObject());
  1470. }
  1471. Entry middle = new Entry(key, value, null);
  1472. // color nodes in non-full bottommost level red
  1473. if (level == redLevel)
  1474. middle.color = RED;
  1475. if (left != null) {
  1476. middle.left = left;
  1477. left.parent = middle;
  1478. }
  1479. if (mid < hi) {
  1480. Entry right = buildFromSorted(level+1, mid+1, hi, redLevel,
  1481. it, str, defaultVal);
  1482. middle.right = right;
  1483. right.parent = middle;
  1484. }
  1485. return middle;
  1486. }
  1487. /**
  1488. * Find the level down to which to assign all nodes BLACK. This is the
  1489. * last `full' level of the complete binary tree produced by
  1490. * buildTree. The remaining nodes are colored RED. (This makes a `nice'
  1491. * set of color assignments wrt future insertions.) This level number is
  1492. * computed by finding the number of splits needed to reach the zeroeth
  1493. * node. (The answer is ~lg(N), but in any case must be computed by same
  1494. * quick O(lg(N)) loop.)
  1495. */
  1496. private static int computeRedLevel(int sz) {
  1497. int level = 0;
  1498. for (int m = sz - 1; m >= 0; m = m / 2 - 1)
  1499. level++;
  1500. return level;
  1501. }
  1502. }