PageRenderTime 70ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/instrumented/java/util/TreeMap.java

https://github.com/dr1861/jcute
Java | 1636 lines | 851 code | 166 blank | 619 comment | 276 complexity | fcf59990a8cd7e6eaeca25f828d74819 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * @(#)TreeMap.java 1.56 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package instrumented.java.util;
  8. /**
  9. * Red-Black tree based implementation of the <tt>SortedMap</tt> interface.
  10. * This class guarantees that the map will be in ascending key order, sorted
  11. * according to the <i>natural order</i> for the key's class (see
  12. * <tt>Comparable</tt>), or by the comparator provided at creation time,
  13. * depending on which constructor is used.<p>
  14. *
  15. * This implementation provides guaranteed log(n) time cost for the
  16. * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and <tt>remove</tt>
  17. * operations. Algorithms are adaptations of those in Cormen, Leiserson, and
  18. * Rivest's <I>Introduction to Algorithms</I>.<p>
  19. *
  20. * Note that the ordering maintained by a sorted map (whether or not an
  21. * explicit comparator is provided) must be <i>consistent with equals</i> if
  22. * this sorted map is to correctly implement the <tt>Map</tt> interface. (See
  23. * <tt>Comparable</tt> or <tt>Comparator</tt> for a precise definition of
  24. * <i>consistent with equals</i>.) This is so because the <tt>Map</tt>
  25. * interface is defined in terms of the equals operation, but a map performs
  26. * all key comparisons using its <tt>compareTo</tt> (or <tt>compare</tt>)
  27. * method, so two keys that are deemed equal by this method are, from the
  28. * standpoint of the sorted map, equal. The behavior of a sorted map
  29. * <i>is</i> well-defined even if its ordering is inconsistent with equals; it
  30. * just fails to obey the general contract of the <tt>Map</tt> interface.<p>
  31. *
  32. * <b>Note that this implementation is not synchronized.</b> If multiple
  33. * threads access a map concurrently, and at least one of the threads modifies
  34. * the map structurally, it <i>must</i> be synchronized externally. (A
  35. * structural modification is any operation that adds or deletes one or more
  36. * mappings; merely changing the value associated with an existing key is not
  37. * a structural modification.) This is typically accomplished by
  38. * synchronizing on some object that naturally encapsulates the map. If no
  39. * such object exists, the map should be "wrapped" using the
  40. * <tt>Collections.synchronizedMap</tt> method. This is best done at creation
  41. * time, to prevent accidental unsynchronized access to the map:
  42. * <pre>
  43. * Map m = Collections.synchronizedMap(new TreeMap(...));
  44. * </pre><p>
  45. *
  46. * The iterators returned by all of this class's "collection view methods" are
  47. * <i>fail-fast</i>: if the map is structurally modified at any time after the
  48. * iterator is created, in any way except through the iterator's own
  49. * <tt>remove</tt> or <tt>add</tt> methods, the iterator throws a
  50. * <tt>ConcurrentModificationException</tt>. Thus, in the face of concurrent
  51. * modification, the iterator fails quickly and cleanly, rather than risking
  52. * arbitrary, non-deterministic behavior at an undetermined time in the
  53. * future.
  54. *
  55. * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
  56. * as it is, generally speaking, impossible to make any hard guarantees in the
  57. * presence of unsynchronized concurrent modification. Fail-fast iterators
  58. * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
  59. * Therefore, it would be wrong to write a program that depended on this
  60. * exception for its correctness: <i>the fail-fast behavior of iterators
  61. * should be used only to detect bugs.</i><p>
  62. *
  63. * This class is a member of the
  64. * <a href="{@docRoot}/../guide/collections/index.html">
  65. * Java Collections Framework</a>.
  66. *
  67. * @author Josh Bloch and Doug Lea
  68. * @version 1.56, 01/23/03
  69. * @see Map
  70. * @see HashMap
  71. * @see Hashtable
  72. * @see Comparable
  73. * @see Comparator
  74. * @see Collection
  75. * @see Collections#synchronizedMap(Map)
  76. * @since 1.2
  77. */
  78. public class TreeMap extends AbstractMap
  79. implements SortedMap, Cloneable, java.io.Serializable
  80. {
  81. /**
  82. * The Comparator used to maintain order in this TreeMap, or
  83. * null if this TreeMap uses its elements natural ordering.
  84. *
  85. * @serial
  86. */
  87. private Comparator comparator = null;
  88. private transient Entry root = null;
  89. /**
  90. * The number of entries in the tree
  91. */
  92. private transient int size = 0;
  93. /**
  94. * The number of structural modifications to the tree.
  95. */
  96. private transient int modCount = 0;
  97. private void incrementSize() { modCount++; size++; }
  98. private void decrementSize() { modCount++; size--; }
  99. /**
  100. * Constructs a new, empty map, sorted according to the keys' natural
  101. * order. All keys inserted into the map must implement the
  102. * <tt>Comparable</tt> interface. Furthermore, all such keys must be
  103. * <i>mutually comparable</i>: <tt>k1.compareTo(k2)</tt> must not throw a
  104. * ClassCastException for any elements <tt>k1</tt> and <tt>k2</tt> in the
  105. * map. If the user attempts to put a key into the map that violates this
  106. * constraint (for example, the user attempts to put a string key into a
  107. * map whose keys are integers), the <tt>put(Object key, Object
  108. * value)</tt> call will throw a <tt>ClassCastException</tt>.
  109. *
  110. * @see Comparable
  111. */
  112. public TreeMap() {
  113. }
  114. /**
  115. * Constructs a new, empty map, sorted according to the given comparator.
  116. * All keys inserted into the map must be <i>mutually comparable</i> by
  117. * the given comparator: <tt>comparator.compare(k1, k2)</tt> must not
  118. * throw a <tt>ClassCastException</tt> for any keys <tt>k1</tt> and
  119. * <tt>k2</tt> in the map. If the user attempts to put a key into the
  120. * map that violates this constraint, the <tt>put(Object key, Object
  121. * value)</tt> call will throw a <tt>ClassCastException</tt>.
  122. *
  123. * @param c the comparator that will be used to sort this map. A
  124. * <tt>null</tt> value indicates that the keys' <i>natural
  125. * ordering</i> should be used.
  126. */
  127. public TreeMap(Comparator c) {
  128. this.comparator = c;
  129. }
  130. /**
  131. * Constructs a new map containing the same mappings as the given map,
  132. * sorted according to the keys' <i>natural order</i>. All keys inserted
  133. * into the new map must implement the <tt>Comparable</tt> interface.
  134. * Furthermore, all such keys must be <i>mutually comparable</i>:
  135. * <tt>k1.compareTo(k2)</tt> must not throw a <tt>ClassCastException</tt>
  136. * for any elements <tt>k1</tt> and <tt>k2</tt> in the map. This method
  137. * runs in n*log(n) time.
  138. *
  139. * @param m the map whose mappings are to be placed in this map.
  140. * @throws ClassCastException the keys in t are not Comparable, or
  141. * are not mutually comparable.
  142. * @throws NullPointerException if the specified map is null.
  143. */
  144. public TreeMap(Map m) {
  145. putAll(m);
  146. }
  147. /**
  148. * Constructs a new map containing the same mappings as the given
  149. * <tt>SortedMap</tt>, sorted according to the same ordering. This method
  150. * runs in linear time.
  151. *
  152. * @param m the sorted map whose mappings are to be placed in this map,
  153. * and whose comparator is to be used to sort this map.
  154. * @throws NullPointerException if the specified sorted map is null.
  155. */
  156. public TreeMap(SortedMap m) {
  157. comparator = m.comparator();
  158. try {
  159. buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
  160. } catch (java.io.IOException cannotHappen) {
  161. } catch (ClassNotFoundException cannotHappen) {
  162. }
  163. }
  164. // Query Operations
  165. /**
  166. * Returns the number of key-value mappings in this map.
  167. *
  168. * @return the number of key-value mappings in this map.
  169. */
  170. public int size() {
  171. return size;
  172. }
  173. /**
  174. * Returns <tt>true</tt> if this map contains a mapping for the specified
  175. * key.
  176. *
  177. * @param key key whose presence in this map is to be tested.
  178. *
  179. * @return <tt>true</tt> if this map contains a mapping for the
  180. * specified key.
  181. * @throws ClassCastException if the key cannot be compared with the keys
  182. * currently in the map.
  183. * @throws NullPointerException key is <tt>null</tt> and this map uses
  184. * natural ordering, or its comparator does not tolerate
  185. * <tt>null</tt> keys.
  186. */
  187. public boolean containsKey(Object key) {
  188. return getEntry(key) != null;
  189. }
  190. /**
  191. * Returns <tt>true</tt> if this map maps one or more keys to the
  192. * specified value. More formally, returns <tt>true</tt> if and only if
  193. * this map contains at least one mapping to a value <tt>v</tt> such
  194. * that <tt>(value==null ? v==null : value.equals(v))</tt>. This
  195. * operation will probably require time linear in the Map size for most
  196. * implementations of Map.
  197. *
  198. * @param value value whose presence in this Map is to be tested.
  199. * @return <tt>true</tt> if a mapping to <tt>value</tt> exists;
  200. * <tt>false</tt> otherwise.
  201. * @since 1.2
  202. */
  203. public boolean containsValue(Object value) {
  204. return (root==null ? false :
  205. (value==null ? valueSearchNull(root)
  206. : valueSearchNonNull(root, value)));
  207. }
  208. private boolean valueSearchNull(Entry n) {
  209. if (n.value == null)
  210. return true;
  211. // Check left and right subtrees for value
  212. return (n.left != null && valueSearchNull(n.left)) ||
  213. (n.right != null && valueSearchNull(n.right));
  214. }
  215. private boolean valueSearchNonNull(Entry n, Object value) {
  216. // Check this node for the value
  217. if (value.equals(n.value))
  218. return true;
  219. // Check left and right subtrees for value
  220. return (n.left != null && valueSearchNonNull(n.left, value)) ||
  221. (n.right != null && valueSearchNonNull(n.right, value));
  222. }
  223. /**
  224. * Returns the value to which this map maps the specified key. Returns
  225. * <tt>null</tt> if the map contains no mapping for this key. A return
  226. * value of <tt>null</tt> does not <i>necessarily</i> indicate that the
  227. * map contains no mapping for the key; it's also possible that the map
  228. * explicitly maps the key to <tt>null</tt>. The <tt>containsKey</tt>
  229. * operation may be used to distinguish these two cases.
  230. *
  231. * @param key key whose associated value is to be returned.
  232. * @return the value to which this map maps the specified key, or
  233. * <tt>null</tt> if the map contains no mapping for the key.
  234. * @throws ClassCastException key cannot be compared with the keys
  235. * currently in the map.
  236. * @throws NullPointerException key is <tt>null</tt> and this map uses
  237. * natural ordering, or its comparator does not tolerate
  238. * <tt>null</tt> keys.
  239. *
  240. * @see #containsKey(Object)
  241. */
  242. public Object get(Object key) {
  243. Entry p = getEntry(key);
  244. return (p==null ? null : p.value);
  245. }
  246. /**
  247. * Returns the comparator used to order this map, or <tt>null</tt> if this
  248. * map uses its keys' natural order.
  249. *
  250. * @return the comparator associated with this sorted map, or
  251. * <tt>null</tt> if it uses its keys' natural sort method.
  252. */
  253. public Comparator comparator() {
  254. return comparator;
  255. }
  256. /**
  257. * Returns the first (lowest) key currently in this sorted map.
  258. *
  259. * @return the first (lowest) key currently in this sorted map.
  260. * @throws NoSuchElementException Map is empty.
  261. */
  262. public Object firstKey() {
  263. return key(firstEntry());
  264. }
  265. /**
  266. * Returns the last (highest) key currently in this sorted map.
  267. *
  268. * @return the last (highest) key currently in this sorted map.
  269. * @throws NoSuchElementException Map is empty.
  270. */
  271. public Object lastKey() {
  272. return key(lastEntry());
  273. }
  274. /**
  275. * Copies all of the mappings from the specified map to this map. These
  276. * mappings replace any mappings that this map had for any of the keys
  277. * currently in the specified map.
  278. *
  279. * @param map mappings to be stored in this map.
  280. * @throws ClassCastException class of a key or value in the specified
  281. * map prevents it from being stored in this map.
  282. *
  283. * @throws NullPointerException if the given map is <tt>null</tt> or
  284. * this map does not permit <tt>null</tt> keys and a
  285. * key in the specified map is <tt>null</tt>.
  286. */
  287. public void putAll(Map map) {
  288. int mapSize = map.size();
  289. if (size==0 && mapSize!=0 && map instanceof SortedMap) {
  290. Comparator c = ((SortedMap)map).comparator();
  291. if (c == comparator || (c != null && c.equals(comparator))) {
  292. ++modCount;
  293. try {
  294. buildFromSorted(mapSize, map.entrySet().iterator(),
  295. null, null);
  296. } catch (java.io.IOException cannotHappen) {
  297. } catch (ClassNotFoundException cannotHappen) {
  298. }
  299. return;
  300. }
  301. }
  302. super.putAll(map);
  303. }
  304. /**
  305. * Returns this map's entry for the given key, or <tt>null</tt> if the map
  306. * does not contain an entry for the key.
  307. *
  308. * @return this map's entry for the given key, or <tt>null</tt> if the map
  309. * does not contain an entry for the key.
  310. * @throws ClassCastException if the key cannot be compared with the keys
  311. * currently in the map.
  312. * @throws NullPointerException key is <tt>null</tt> and this map uses
  313. * natural order, or its comparator does not tolerate *
  314. * <tt>null</tt> keys.
  315. */
  316. private Entry getEntry(Object key) {
  317. Entry p = root;
  318. while (p != null) {
  319. int cmp = compare(key,p.key);
  320. if (cmp == 0)
  321. return p;
  322. else if (cmp < 0)
  323. p = p.left;
  324. else
  325. p = p.right;
  326. }
  327. return null;
  328. }
  329. /**
  330. * Gets the entry corresponding to the specified key; if no such entry
  331. * exists, returns the entry for the least key greater than the specified
  332. * key; if no such entry exists (i.e., the greatest key in the Tree is less
  333. * than the specified key), returns <tt>null</tt>.
  334. */
  335. private Entry getCeilEntry(Object key) {
  336. Entry p = root;
  337. if (p==null)
  338. return null;
  339. while (true) {
  340. int cmp = compare(key, p.key);
  341. if (cmp == 0) {
  342. return p;
  343. } else if (cmp < 0) {
  344. if (p.left != null)
  345. p = p.left;
  346. else
  347. return p;
  348. } else {
  349. if (p.right != null) {
  350. p = p.right;
  351. } else {
  352. Entry parent = p.parent;
  353. Entry ch = p;
  354. while (parent != null && ch == parent.right) {
  355. ch = parent;
  356. parent = parent.parent;
  357. }
  358. return parent;
  359. }
  360. }
  361. }
  362. }
  363. /**
  364. * Returns the entry for the greatest key less than the specified key; if
  365. * no such entry exists (i.e., the least key in the Tree is greater than
  366. * the specified key), returns <tt>null</tt>.
  367. */
  368. private Entry getPrecedingEntry(Object key) {
  369. Entry p = root;
  370. if (p==null)
  371. return null;
  372. while (true) {
  373. int cmp = compare(key, p.key);
  374. if (cmp > 0) {
  375. if (p.right != null)
  376. p = p.right;
  377. else
  378. return p;
  379. } else {
  380. if (p.left != null) {
  381. p = p.left;
  382. } else {
  383. Entry parent = p.parent;
  384. Entry ch = p;
  385. while (parent != null && ch == parent.left) {
  386. ch = parent;
  387. parent = parent.parent;
  388. }
  389. return parent;
  390. }
  391. }
  392. }
  393. }
  394. /**
  395. * Returns the key corresonding to the specified Entry. Throw
  396. * NoSuchElementException if the Entry is <tt>null</tt>.
  397. */
  398. private static Object key(Entry e) {
  399. if (e==null)
  400. throw new NoSuchElementException();
  401. return e.key;
  402. }
  403. /**
  404. * Associates the specified value with the specified key in this map.
  405. * If the map previously contained a mapping for this key, the old
  406. * value is replaced.
  407. *
  408. * @param key key with which the specified value is to be associated.
  409. * @param value value to be associated with the specified key.
  410. *
  411. * @return previous value associated with specified key, or <tt>null</tt>
  412. * if there was no mapping for key. A <tt>null</tt> return can
  413. * also indicate that the map previously associated <tt>null</tt>
  414. * with the specified key.
  415. * @throws ClassCastException key cannot be compared with the keys
  416. * currently in the map.
  417. * @throws NullPointerException key is <tt>null</tt> and this map uses
  418. * natural order, or its comparator does not tolerate
  419. * <tt>null</tt> keys.
  420. */
  421. public Object put(Object key, Object value) {
  422. Entry t = root;
  423. if (t == null) {
  424. incrementSize();
  425. root = new Entry(key, value, null);
  426. return null;
  427. }
  428. while (true) {
  429. int cmp = compare(key, t.key);
  430. if (cmp == 0) {
  431. return t.setValue(value);
  432. } else if (cmp < 0) {
  433. if (t.left != null) {
  434. t = t.left;
  435. } else {
  436. incrementSize();
  437. t.left = new Entry(key, value, t);
  438. fixAfterInsertion(t.left);
  439. return null;
  440. }
  441. } else { // cmp > 0
  442. if (t.right != null) {
  443. t = t.right;
  444. } else {
  445. incrementSize();
  446. t.right = new Entry(key, value, t);
  447. fixAfterInsertion(t.right);
  448. return null;
  449. }
  450. }
  451. }
  452. }
  453. /**
  454. * Removes the mapping for this key from this TreeMap if present.
  455. *
  456. * @param key key for which mapping should be removed
  457. * @return previous value associated with specified key, or <tt>null</tt>
  458. * if there was no mapping for key. A <tt>null</tt> return can
  459. * also indicate that the map previously associated
  460. * <tt>null</tt> with the specified key.
  461. *
  462. * @throws ClassCastException key cannot be compared with the keys
  463. * currently in the map.
  464. * @throws NullPointerException key is <tt>null</tt> and this map uses
  465. * natural order, or its comparator does not tolerate
  466. * <tt>null</tt> keys.
  467. */
  468. public Object remove(Object key) {
  469. Entry p = getEntry(key);
  470. if (p == null)
  471. return null;
  472. Object oldValue = p.value;
  473. deleteEntry(p);
  474. return oldValue;
  475. }
  476. /**
  477. * Removes all mappings from this TreeMap.
  478. */
  479. public void clear() {
  480. modCount++;
  481. size = 0;
  482. root = null;
  483. }
  484. /**
  485. * Returns a shallow copy of this <tt>TreeMap</tt> instance. (The keys and
  486. * values themselves are not cloned.)
  487. *
  488. * @return a shallow copy of this Map.
  489. */
  490. public Object clone() {
  491. TreeMap clone = null;
  492. try {
  493. clone = (TreeMap)super.clone();
  494. } catch (CloneNotSupportedException e) {
  495. throw new InternalError();
  496. }
  497. // Put clone into "virgin" state (except for comparator)
  498. clone.root = null;
  499. clone.size = 0;
  500. clone.modCount = 0;
  501. clone.entrySet = null;
  502. // Initialize clone with our mappings
  503. try {
  504. clone.buildFromSorted(size, entrySet().iterator(), null, null);
  505. } catch (java.io.IOException cannotHappen) {
  506. } catch (ClassNotFoundException cannotHappen) {
  507. }
  508. return clone;
  509. }
  510. // Views
  511. /**
  512. * This field is initialized to contain an instance of the entry set
  513. * view the first time this view is requested. The view is stateless,
  514. * so there's no reason to create more than one.
  515. */
  516. private transient volatile Set entrySet = null;
  517. /**
  518. * Returns a Set view of the keys contained in this map. The set's
  519. * iterator will return the keys in ascending order. The map is backed by
  520. * this <tt>TreeMap</tt> instance, so changes to this map are reflected in
  521. * the Set, and vice-versa. The Set supports element removal, which
  522. * removes the corresponding mapping from the map, via the
  523. * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt>,
  524. * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not support
  525. * the <tt>add</tt> or <tt>addAll</tt> operations.
  526. *
  527. * @return a set view of the keys contained in this TreeMap.
  528. */
  529. public Set keySet() {
  530. if (keySet == null) {
  531. keySet = new AbstractSet() {
  532. public Iterator iterator() {
  533. return new KeyIterator();
  534. }
  535. public int size() {
  536. return TreeMap.this.size();
  537. }
  538. public boolean contains(Object o) {
  539. return containsKey(o);
  540. }
  541. public boolean remove(Object o) {
  542. int oldSize = size;
  543. TreeMap.this.remove(o);
  544. return size != oldSize;
  545. }
  546. public void clear() {
  547. TreeMap.this.clear();
  548. }
  549. };
  550. }
  551. return keySet;
  552. }
  553. /**
  554. * Returns a collection view of the values contained in this map. The
  555. * collection's iterator will return the values in the order that their
  556. * corresponding keys appear in the tree. The collection is backed by
  557. * this <tt>TreeMap</tt> instance, so changes to this map are reflected in
  558. * the collection, and vice-versa. The collection supports element
  559. * removal, which removes the corresponding mapping from the map through
  560. * the <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
  561. * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
  562. * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
  563. *
  564. * @return a collection view of the values contained in this map.
  565. */
  566. public Collection values() {
  567. if (values == null) {
  568. values = new AbstractCollection() {
  569. public Iterator iterator() {
  570. return new ValueIterator();
  571. }
  572. public int size() {
  573. return TreeMap.this.size();
  574. }
  575. public boolean contains(Object o) {
  576. for (Entry e = firstEntry(); e != null; e = successor(e))
  577. if (valEquals(e.getValue(), o))
  578. return true;
  579. return false;
  580. }
  581. public boolean remove(Object o) {
  582. for (Entry e = firstEntry(); e != null; e = successor(e)) {
  583. if (valEquals(e.getValue(), o)) {
  584. deleteEntry(e);
  585. return true;
  586. }
  587. }
  588. return false;
  589. }
  590. public void clear() {
  591. TreeMap.this.clear();
  592. }
  593. };
  594. }
  595. return values;
  596. }
  597. /**
  598. * Returns a set view of the mappings contained in this map. The set's
  599. * iterator returns the mappings in ascending key order. Each element in
  600. * the returned set is a <tt>Map.Entry</tt>. The set is backed by this
  601. * map, so changes to this map are reflected in the set, and vice-versa.
  602. * The set supports element removal, which removes the corresponding
  603. * mapping from the TreeMap, through the <tt>Iterator.remove</tt>,
  604. * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
  605. * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
  606. * <tt>addAll</tt> operations.
  607. *
  608. * @return a set view of the mappings contained in this map.
  609. * @see Map.Entry
  610. */
  611. public Set entrySet() {
  612. if (entrySet == null) {
  613. entrySet = new AbstractSet() {
  614. public Iterator iterator() {
  615. return new EntryIterator();
  616. }
  617. public boolean contains(Object o) {
  618. if (!(o instanceof Map.Entry))
  619. return false;
  620. Map.Entry entry = (Map.Entry)o;
  621. Object value = entry.getValue();
  622. Entry p = getEntry(entry.getKey());
  623. return p != null && valEquals(p.getValue(), value);
  624. }
  625. public boolean remove(Object o) {
  626. if (!(o instanceof Map.Entry))
  627. return false;
  628. Map.Entry entry = (Map.Entry)o;
  629. Object value = entry.getValue();
  630. Entry p = getEntry(entry.getKey());
  631. if (p != null && valEquals(p.getValue(), value)) {
  632. deleteEntry(p);
  633. return true;
  634. }
  635. return false;
  636. }
  637. public int size() {
  638. return TreeMap.this.size();
  639. }
  640. public void clear() {
  641. TreeMap.this.clear();
  642. }
  643. };
  644. }
  645. return entrySet;
  646. }
  647. /**
  648. * Returns a view of the portion of this map whose keys range from
  649. * <tt>fromKey</tt>, inclusive, to <tt>toKey</tt>, exclusive. (If
  650. * <tt>fromKey</tt> and <tt>toKey</tt> are equal, the returned sorted map
  651. * is empty.) The returned sorted map is backed by this map, so changes
  652. * in the returned sorted map are reflected in this map, and vice-versa.
  653. * The returned sorted map supports all optional map operations.<p>
  654. *
  655. * The sorted map returned by this method will throw an
  656. * <tt>IllegalArgumentException</tt> if the user attempts to insert a key
  657. * less than <tt>fromKey</tt> or greater than or equal to
  658. * <tt>toKey</tt>.<p>
  659. *
  660. * Note: this method always returns a <i>half-open range</i> (which
  661. * includes its low endpoint but not its high endpoint). If you need a
  662. * <i>closed range</i> (which includes both endpoints), and the key type
  663. * allows for calculation of the successor a given key, merely request the
  664. * subrange from <tt>lowEndpoint</tt> to <tt>successor(highEndpoint)</tt>.
  665. * For example, suppose that <tt>m</tt> is a sorted map whose keys are
  666. * strings. The following idiom obtains a view containing all of the
  667. * key-value mappings in <tt>m</tt> whose keys are between <tt>low</tt>
  668. * and <tt>high</tt>, inclusive:
  669. * <pre> SortedMap sub = m.submap(low, high+"\0");</pre>
  670. * A similar technique can be used to generate an <i>open range</i> (which
  671. * contains neither endpoint). The following idiom obtains a view
  672. * containing all of the key-value mappings in <tt>m</tt> whose keys are
  673. * between <tt>low</tt> and <tt>high</tt>, exclusive:
  674. * <pre> SortedMap sub = m.subMap(low+"\0", high);</pre>
  675. *
  676. * @param fromKey low endpoint (inclusive) of the subMap.
  677. * @param toKey high endpoint (exclusive) of the subMap.
  678. *
  679. * @return a view of the portion of this map whose keys range from
  680. * <tt>fromKey</tt>, inclusive, to <tt>toKey</tt>, exclusive.
  681. *
  682. * @throws ClassCastException if <tt>fromKey</tt> and <tt>toKey</tt>
  683. * cannot be compared to one another using this map's comparator
  684. * (or, if the map has no comparator, using natural ordering).
  685. * @throws IllegalArgumentException if <tt>fromKey</tt> is greater than
  686. * <tt>toKey</tt>.
  687. * @throws NullPointerException if <tt>fromKey</tt> or <tt>toKey</tt> is
  688. * <tt>null</tt> and this map uses natural order, or its
  689. * comparator does not tolerate <tt>null</tt> keys.
  690. */
  691. public SortedMap subMap(Object fromKey, Object toKey) {
  692. return new SubMap(fromKey, toKey);
  693. }
  694. /**
  695. * Returns a view of the portion of this map whose keys are strictly less
  696. * than <tt>toKey</tt>. The returned sorted map is backed by this map, so
  697. * changes in the returned sorted map are reflected in this map, and
  698. * vice-versa. The returned sorted map supports all optional map
  699. * operations.<p>
  700. *
  701. * The sorted map returned by this method will throw an
  702. * <tt>IllegalArgumentException</tt> if the user attempts to insert a key
  703. * greater than or equal to <tt>toKey</tt>.<p>
  704. *
  705. * Note: this method always returns a view that does not contain its
  706. * (high) endpoint. If you need a view that does contain this endpoint,
  707. * and the key type allows for calculation of the successor a given key,
  708. * merely request a headMap bounded by <tt>successor(highEndpoint)</tt>.
  709. * For example, suppose that suppose that <tt>m</tt> is a sorted map whose
  710. * keys are strings. The following idiom obtains a view containing all of
  711. * the key-value mappings in <tt>m</tt> whose keys are less than or equal
  712. * to <tt>high</tt>:
  713. * <pre>
  714. * SortedMap head = m.headMap(high+"\0");
  715. * </pre>
  716. *
  717. * @param toKey high endpoint (exclusive) of the headMap.
  718. * @return a view of the portion of this map whose keys are strictly
  719. * less than <tt>toKey</tt>.
  720. *
  721. * @throws ClassCastException if <tt>toKey</tt> is not compatible
  722. * with this map's comparator (or, if the map has no comparator,
  723. * if <tt>toKey</tt> does not implement <tt>Comparable</tt>).
  724. * @throws IllegalArgumentException if this map is itself a subMap,
  725. * headMap, or tailMap, and <tt>toKey</tt> is not within the
  726. * specified range of the subMap, headMap, or tailMap.
  727. * @throws NullPointerException if <tt>toKey</tt> is <tt>null</tt> and
  728. * this map uses natural order, or its comparator does not
  729. * tolerate <tt>null</tt> keys.
  730. */
  731. public SortedMap headMap(Object toKey) {
  732. return new SubMap(toKey, true);
  733. }
  734. /**
  735. * Returns a view of the portion of this map whose keys are greater than
  736. * or equal to <tt>fromKey</tt>. The returned sorted map is backed by
  737. * this map, so changes in the returned sorted map are reflected in this
  738. * map, and vice-versa. The returned sorted map supports all optional map
  739. * operations.<p>
  740. *
  741. * The sorted map returned by this method will throw an
  742. * <tt>IllegalArgumentException</tt> if the user attempts to insert a key
  743. * less than <tt>fromKey</tt>.<p>
  744. *
  745. * Note: this method always returns a view that contains its (low)
  746. * endpoint. If you need a view that does not contain this endpoint, and
  747. * the element type allows for calculation of the successor a given value,
  748. * merely request a tailMap bounded by <tt>successor(lowEndpoint)</tt>.
  749. * For For example, suppose that suppose that <tt>m</tt> is a sorted map
  750. * whose keys are strings. The following idiom obtains a view containing
  751. * all of the key-value mappings in <tt>m</tt> whose keys are strictly
  752. * greater than <tt>low</tt>: <pre>
  753. * SortedMap tail = m.tailMap(low+"\0");
  754. * </pre>
  755. *
  756. * @param fromKey low endpoint (inclusive) of the tailMap.
  757. * @return a view of the portion of this map whose keys are greater
  758. * than or equal to <tt>fromKey</tt>.
  759. * @throws ClassCastException if <tt>fromKey</tt> is not compatible
  760. * with this map's comparator (or, if the map has no comparator,
  761. * if <tt>fromKey</tt> does not implement <tt>Comparable</tt>).
  762. * @throws IllegalArgumentException if this map is itself a subMap,
  763. * headMap, or tailMap, and <tt>fromKey</tt> is not within the
  764. * specified range of the subMap, headMap, or tailMap.
  765. * @throws NullPointerException if <tt>fromKey</tt> is <tt>null</tt> and
  766. * this map uses natural order, or its comparator does not
  767. * tolerate <tt>null</tt> keys.
  768. */
  769. public SortedMap tailMap(Object fromKey) {
  770. return new SubMap(fromKey, false);
  771. }
  772. private class SubMap extends AbstractMap
  773. implements SortedMap, java.io.Serializable {
  774. private static final long serialVersionUID = -6520786458950516097L;
  775. /**
  776. * fromKey is significant only if fromStart is false. Similarly,
  777. * toKey is significant only if toStart is false.
  778. */
  779. private boolean fromStart = false, toEnd = false;
  780. private Object fromKey, toKey;
  781. SubMap(Object fromKey, Object toKey) {
  782. if (compare(fromKey, toKey) > 0)
  783. throw new IllegalArgumentException("fromKey > toKey");
  784. this.fromKey = fromKey;
  785. this.toKey = toKey;
  786. }
  787. SubMap(Object key, boolean headMap) {
  788. compare(key, key); // Type-check key
  789. if (headMap) {
  790. fromStart = true;
  791. toKey = key;
  792. } else {
  793. toEnd = true;
  794. fromKey = key;
  795. }
  796. }
  797. SubMap(boolean fromStart, Object fromKey, boolean toEnd, Object toKey){
  798. this.fromStart = fromStart;
  799. this.fromKey= fromKey;
  800. this.toEnd = toEnd;
  801. this.toKey = toKey;
  802. }
  803. public boolean isEmpty() {
  804. return entrySet.isEmpty();
  805. }
  806. public boolean containsKey(Object key) {
  807. return inRange(key) && TreeMap.this.containsKey(key);
  808. }
  809. public Object get(Object key) {
  810. if (!inRange(key))
  811. return null;
  812. return TreeMap.this.get(key);
  813. }
  814. public Object put(Object key, Object value) {
  815. if (!inRange(key))
  816. throw new IllegalArgumentException("key out of range");
  817. return TreeMap.this.put(key, value);
  818. }
  819. public Comparator comparator() {
  820. return comparator;
  821. }
  822. public Object firstKey() {
  823. Object first = key(fromStart ? firstEntry():getCeilEntry(fromKey));
  824. if (!toEnd && compare(first, toKey) >= 0)
  825. throw(new NoSuchElementException());
  826. return first;
  827. }
  828. public Object lastKey() {
  829. Object last = key(toEnd ? lastEntry() : getPrecedingEntry(toKey));
  830. if (!fromStart && compare(last, fromKey) < 0)
  831. throw(new NoSuchElementException());
  832. return last;
  833. }
  834. private transient Set entrySet = new EntrySetView();
  835. public Set entrySet() {
  836. return entrySet;
  837. }
  838. private class EntrySetView extends AbstractSet {
  839. private transient int size = -1, sizeModCount;
  840. public int size() {
  841. if (size == -1 || sizeModCount != TreeMap.this.modCount) {
  842. size = 0; sizeModCount = TreeMap.this.modCount;
  843. Iterator i = iterator();
  844. while (i.hasNext()) {
  845. size++;
  846. i.next();
  847. }
  848. }
  849. return size;
  850. }
  851. public boolean isEmpty() {
  852. return !iterator().hasNext();
  853. }
  854. public boolean contains(Object o) {
  855. if (!(o instanceof Map.Entry))
  856. return false;
  857. Map.Entry entry = (Map.Entry)o;
  858. Object key = entry.getKey();
  859. if (!inRange(key))
  860. return false;
  861. TreeMap.Entry node = getEntry(key);
  862. return node != null &&
  863. valEquals(node.getValue(), entry.getValue());
  864. }
  865. public boolean remove(Object o) {
  866. if (!(o instanceof Map.Entry))
  867. return false;
  868. Map.Entry entry = (Map.Entry)o;
  869. Object key = entry.getKey();
  870. if (!inRange(key))
  871. return false;
  872. TreeMap.Entry node = getEntry(key);
  873. if (node!=null && valEquals(node.getValue(),entry.getValue())){
  874. deleteEntry(node);
  875. return true;
  876. }
  877. return false;
  878. }
  879. public Iterator iterator() {
  880. return new SubMapEntryIterator(
  881. (fromStart ? firstEntry() : getCeilEntry(fromKey)),
  882. (toEnd ? null : getCeilEntry(toKey)));
  883. }
  884. }
  885. public SortedMap subMap(Object fromKey, Object toKey) {
  886. if (!inRange2(fromKey))
  887. throw new IllegalArgumentException("fromKey out of range");
  888. if (!inRange2(toKey))
  889. throw new IllegalArgumentException("toKey out of range");
  890. return new SubMap(fromKey, toKey);
  891. }
  892. public SortedMap headMap(Object toKey) {
  893. if (!inRange2(toKey))
  894. throw new IllegalArgumentException("toKey out of range");
  895. return new SubMap(fromStart, fromKey, false, toKey);
  896. }
  897. public SortedMap tailMap(Object fromKey) {
  898. if (!inRange2(fromKey))
  899. throw new IllegalArgumentException("fromKey out of range");
  900. return new SubMap(false, fromKey, toEnd, toKey);
  901. }
  902. private boolean inRange(Object key) {
  903. return (fromStart || compare(key, fromKey) >= 0) &&
  904. (toEnd || compare(key, toKey) < 0);
  905. }
  906. // This form allows the high endpoint (as well as all legit keys)
  907. private boolean inRange2(Object key) {
  908. return (fromStart || compare(key, fromKey) >= 0) &&
  909. (toEnd || compare(key, toKey) <= 0);
  910. }
  911. }
  912. /**
  913. * TreeMap Iterator.
  914. */
  915. private class EntryIterator implements Iterator {
  916. private int expectedModCount = TreeMap.this.modCount;
  917. private Entry lastReturned = null;
  918. Entry next;
  919. EntryIterator() {
  920. next = firstEntry();
  921. }
  922. // Used by SubMapEntryIterator
  923. EntryIterator(Entry first) {
  924. next = first;
  925. }
  926. public boolean hasNext() {
  927. return next != null;
  928. }
  929. final Entry nextEntry() {
  930. if (next == null)
  931. throw new NoSuchElementException();
  932. if (modCount != expectedModCount)
  933. throw new ConcurrentModificationException();
  934. lastReturned = next;
  935. next = successor(next);
  936. return lastReturned;
  937. }
  938. public Object next() {
  939. return nextEntry();
  940. }
  941. public void remove() {
  942. if (lastReturned == null)
  943. throw new IllegalStateException();
  944. if (modCount != expectedModCount)
  945. throw new ConcurrentModificationException();
  946. if (lastReturned.left != null && lastReturned.right != null)
  947. next = lastReturned;
  948. deleteEntry(lastReturned);
  949. expectedModCount++;
  950. lastReturned = null;
  951. }
  952. }
  953. private class KeyIterator extends EntryIterator {
  954. public Object next() {
  955. return nextEntry().key;
  956. }
  957. }
  958. private class ValueIterator extends EntryIterator {
  959. public Object next() {
  960. return nextEntry().value;
  961. }
  962. }
  963. private class SubMapEntryIterator extends EntryIterator {
  964. private final Object firstExcludedKey;
  965. SubMapEntryIterator(Entry first, Entry firstExcluded) {
  966. super(first);
  967. firstExcludedKey = (firstExcluded == null ?
  968. firstExcluded : firstExcluded.key);
  969. }
  970. public boolean hasNext() {
  971. return next != null && next.key != firstExcludedKey;
  972. }
  973. public Object next() {
  974. if (next == null || next.key == firstExcludedKey)
  975. throw new NoSuchElementException();
  976. return nextEntry();
  977. }
  978. }
  979. /**
  980. * Compares two keys using the correct comparison method for this TreeMap.
  981. */
  982. private int compare(Object k1, Object k2) {
  983. return (comparator==null ? ((Comparable)k1).compareTo(k2)
  984. : comparator.compare(k1, k2));
  985. }
  986. /**
  987. * Test two values for equality. Differs from o1.equals(o2) only in
  988. * that it copes with with <tt>null</tt> o1 properly.
  989. */
  990. private static boolean valEquals(Object o1, Object o2) {
  991. return (o1==null ? o2==null : o1.equals(o2));
  992. }
  993. private static final boolean RED = false;
  994. private static final boolean BLACK = true;
  995. /**
  996. * Node in the Tree. Doubles as a means to pass key-value pairs back to
  997. * user (see Map.Entry).
  998. */
  999. static class Entry implements Map.Entry {
  1000. Object key;
  1001. Object value;
  1002. Entry left = null;
  1003. Entry right = null;
  1004. Entry parent;
  1005. boolean color = BLACK;
  1006. /**
  1007. * Make a new cell with given key, value, and parent, and with
  1008. * <tt>null</tt> child links, and BLACK color.
  1009. */
  1010. Entry(Object key, Object value, Entry parent) {
  1011. this.key = key;
  1012. this.value = value;
  1013. this.parent = parent;
  1014. }
  1015. /**
  1016. * Returns the key.
  1017. *
  1018. * @return the key.
  1019. */
  1020. public Object getKey() {
  1021. return key;
  1022. }
  1023. /**
  1024. * Returns the value associated with the key.
  1025. *
  1026. * @return the value associated with the key.
  1027. */
  1028. public Object getValue() {
  1029. return value;
  1030. }
  1031. /**
  1032. * Replaces the value currently associated with the key with the given
  1033. * value.
  1034. *
  1035. * @return the value associated with the key before this method was
  1036. * called.
  1037. */
  1038. public Object setValue(Object value) {
  1039. Object oldValue = this.value;
  1040. this.value = value;
  1041. return oldValue;
  1042. }
  1043. public boolean equals(Object o) {
  1044. if (!(o instanceof Map.Entry))
  1045. return false;
  1046. Map.Entry e = (Map.Entry)o;
  1047. return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
  1048. }
  1049. public int hashCode() {
  1050. int keyHash = (key==null ? 0 : key.hashCode());
  1051. int valueHash = (value==null ? 0 : value.hashCode());
  1052. return keyHash ^ valueHash;
  1053. }
  1054. public String toString() {
  1055. return key + "=" + value;
  1056. }
  1057. }
  1058. /**
  1059. * Returns the first Entry in the TreeMap (according to the TreeMap's
  1060. * key-sort function). Returns null if the TreeMap is empty.
  1061. */
  1062. private Entry firstEntry() {
  1063. Entry p = root;
  1064. if (p != null)
  1065. while (p.left != null)
  1066. p = p.left;
  1067. return p;
  1068. }
  1069. /**
  1070. * Returns the last Entry in the TreeMap (according to the TreeMap's
  1071. * key-sort function). Returns null if the TreeMap is empty.
  1072. */
  1073. private Entry lastEntry() {
  1074. Entry p = root;
  1075. if (p != null)
  1076. while (p.right != null)
  1077. p = p.right;
  1078. return p;
  1079. }
  1080. /**
  1081. * Returns the successor of the specified Entry, or null if no such.
  1082. */
  1083. private Entry successor(Entry t) {
  1084. if (t == null)
  1085. return null;
  1086. else if (t.right != null) {
  1087. Entry p = t.right;
  1088. while (p.left != null)
  1089. p = p.left;
  1090. return p;
  1091. } else {
  1092. Entry p = t.parent;
  1093. Entry ch = t;
  1094. while (p != null && ch == p.right) {
  1095. ch = p;
  1096. p = p.parent;
  1097. }
  1098. return p;
  1099. }
  1100. }
  1101. /**
  1102. * Balancing operations.
  1103. *
  1104. * Implementations of rebalancings during insertion and deletion are
  1105. * slightly different than the CLR version. Rather than using dummy
  1106. * nilnodes, we use a set of accessors that deal properly with null. They
  1107. * are used to avoid messiness surrounding nullness checks in the main
  1108. * algorithms.
  1109. */
  1110. private static boolean colorOf(Entry p) {
  1111. return (p == null ? BLACK : p.color);
  1112. }
  1113. private static Entry parentOf(Entry p) {
  1114. return (p == null ? null: p.parent);
  1115. }
  1116. private static void setColor(Entry p, boolean c) {
  1117. if (p != null) p.color = c;
  1118. }
  1119. private static Entry leftOf(Entry p) {
  1120. return (p == null)? null: p.left;
  1121. }
  1122. private static Entry rightOf(Entry p) {
  1123. return (p == null)? null: p.right;
  1124. }
  1125. /** From CLR **/
  1126. private void rotateLeft(Entry p) {
  1127. Entry r = p.right;
  1128. p.right = r.left;
  1129. if (r.left != null)
  1130. r.left.parent = p;
  1131. r.parent = p.parent;
  1132. if (p.parent == null)
  1133. root = r;
  1134. else if (p.parent.left == p)
  1135. p.parent.left = r;
  1136. else
  1137. p.parent.right = r;
  1138. r.left = p;
  1139. p.parent = r;
  1140. }
  1141. /** From CLR **/
  1142. private void rotateRight(Entry p) {
  1143. Entry l = p.left;
  1144. p.left = l.right;
  1145. if (l.right != null) l.right.parent = p;
  1146. l.parent = p.parent;
  1147. if (p.parent == null)
  1148. root = l;
  1149. else if (p.parent.right == p)
  1150. p.parent.right = l;
  1151. else p.parent.left = l;
  1152. l.right = p;
  1153. p.parent = l;
  1154. }
  1155. /** From CLR **/
  1156. private void fixAfterInsertion(Entry x) {
  1157. x.color = RED;
  1158. while (x != null && x != root && x.parent.color == RED) {
  1159. if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
  1160. Entry y = rightOf(parentOf(parentOf(x)));
  1161. if (colorOf(y) == RED) {
  1162. setColor(parentOf(x), BLACK);
  1163. setColor(y, BLACK);
  1164. setColor(parentOf(parentOf(x)), RED);
  1165. x = parentOf(parentOf(x));
  1166. } else {
  1167. if (x == rightOf(parentOf(x))) {
  1168. x = parentOf(x);
  1169. rotateLeft(x);
  1170. }
  1171. setColor(parentOf(x), BLACK);
  1172. setColor(parentOf(parentOf(x)), RED);
  1173. if (parentOf(parentOf(x)) != null)
  1174. rotateRight(parentOf(parentOf(x)));
  1175. }
  1176. } else {
  1177. Entry y = leftOf(parentOf(parentOf(x)));
  1178. if (colorOf(y) == RED) {
  1179. setColor(parentOf(x), BLACK);
  1180. setColor(y, BLACK);
  1181. setColor(parentOf(parentOf(x)), RED);
  1182. x = parentOf(parentOf(x));
  1183. } else {
  1184. if (x == leftOf(parentOf(x))) {
  1185. x = parentOf(x);
  1186. rotateRight(x);
  1187. }
  1188. setColor(parentOf(x), BLACK);
  1189. setColor(parentOf(parentOf(x)), RED);
  1190. if (parentOf(parentOf(x)) != null)
  1191. rotateLeft(parentOf(parentOf(x)));
  1192. }
  1193. }
  1194. }
  1195. root.color = BLACK;
  1196. }
  1197. /**
  1198. * Delete node p, and then rebalance the tree.
  1199. */
  1200. private void deleteEntry(Entry p) {
  1201. decrementSize();
  1202. // If strictly internal, copy successor's element to p and then make p
  1203. // point to successor.
  1204. if (p.left != null && p.right != null) {
  1205. Entry s = successor (p);
  1206. p.key = s.key;
  1207. p.value = s.value;
  1208. p = s;
  1209. } // p has 2 children
  1210. // Start fixup at replacement node, if it exists.
  1211. Entry replacement = (p.left != null ? p.left : p.right);
  1212. if (replacement != null) {
  1213. // Link replacement to parent
  1214. replacement.parent = p.parent;
  1215. if (p.parent == null)
  1216. root = replacement;
  1217. else if (p == p.parent.left)
  1218. p.parent.left = replacement;
  1219. else
  1220. p.parent.right = replacement;
  1221. // Null out links so they are OK to use by fixAfterDeletion.
  1222. p.left = p.right = p.parent = null;
  1223. // Fix replacement
  1224. if (p.color == BLACK)
  1225. fixAfterDeletion(replacement);
  1226. } else if (p.parent == null) { // return if we are the only node.
  1227. root = null;
  1228. } else { // No children. Use self as phantom replacement and unlink.
  1229. if (p.color == BLACK)
  1230. fixAfterDeletion(p);
  1231. if (p.parent != null) {
  1232. if (p == p.parent.left)
  1233. p.paren

Large files files are truncated, but you can click here to view the full file