1 /* TreeMap.java -- a class providing a basic Red-Black Tree data structure,
2 mapping Object --> Object
3 Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 As a special exception, if you link this library with other files to
23 produce an executable, this library does not by itself cause the
24 resulting executable to be covered by the GNU General Public License.
25 This exception does not however invalidate any other reasons why the
26 executable file might be covered by the GNU General Public License. */
31 import java
.io
.Serializable
;
32 import java
.io
.ObjectOutputStream
;
33 import java
.io
.ObjectInputStream
;
34 import java
.io
.IOException
;
37 * This class provides a red-black tree implementation of the SortedMap
38 * interface. Elements in the Map will be sorted by either a user-provided
39 * Comparator object, or by the natural ordering of the keys.
41 * The algorithms are adopted from Corman, Leiserson, and Rivest's
42 * <i>Introduction to Algorithms.</i> TreeMap guarantees O(log n)
43 * insertion and deletion of elements. That being said, there is a large
44 * enough constant coefficient in front of that "log n" (overhead involved
45 * in keeping the tree balanced), that TreeMap may not be the best choice
46 * for small collections. If something is already sorted, you may want to
47 * just use a LinkedHashMap to maintain the order while providing O(1) access.
49 * TreeMap is a part of the JDK1.2 Collections API. Null keys are allowed
50 * only if a Comparator is used which can deal with them; natural ordering
51 * cannot cope with null. Null values are always allowed. Note that the
52 * ordering must be <i>consistent with equals</i> to correctly implement
53 * the Map interface. If this condition is violated, the map is still
54 * well-behaved, but you may have suprising results when comparing it to
57 * This implementation is not synchronized. If you need to share this between
58 * multiple threads, do something like:<br>
60 * = Collections.synchronizedSortedMap(new TreeMap(...));</code><p>
62 * The iterators are <i>fail-fast</i>, meaning that any structural
63 * modification, except for <code>remove()</code> called on the iterator
64 * itself, cause the iterator to throw a
65 * <code>ConcurrentModificationException</code> rather than exhibit
66 * non-deterministic behavior.
68 * @author Jon Zeppieri
69 * @author Bryce McKinlay
70 * @author Eric Blake <ebb9@email.byu.edu>
78 * @see Collections#synchronizedSortedMap(SortedMap)
80 * @status updated to 1.4
82 public class TreeMap
extends AbstractMap
83 implements SortedMap
, Cloneable
, Serializable
85 // Implementation note:
86 // A red-black tree is a binary search tree with the additional properties
87 // that all paths to a leaf node visit the same number of black nodes,
88 // and no red node has red children. To avoid some null-pointer checks,
89 // we use the special node nil which is always black, has no relatives,
90 // and has key and value of null (but is not equal to a mapping of null).
93 * Compatible with JDK 1.2.
95 private static final long serialVersionUID
= 919286545866124006L;
98 * Color status of a node. Package visible for use by nested classes.
100 static final int RED
= -1,
104 * Sentinal node, used to avoid null checks for corner cases and make the
105 * delete rebalance code simpler. The rebalance code must never assign
106 * the parent, left, or right of nil, but may safely reassign the color
107 * to be black. This object must never be used as a key in a TreeMap, or
108 * it will break bounds checking of a SubMap.
110 static final Node nil
= new Node(null, null, BLACK
);
113 // Nil is self-referential, so we must initialize it after creation.
120 * The root node of this TreeMap.
122 private transient Node root
= nil
;
125 * The size of this TreeMap. Package visible for use by nested classes.
130 * The cache for {@link #entrySet()}.
132 private transient Set entries
;
135 * Counts the number of modifications this TreeMap has undergone, used
136 * by Iterators to know when to throw ConcurrentModificationExceptions.
137 * Package visible for use by nested classes.
139 transient int modCount
;
142 * This TreeMap's comparator, or null for natural ordering.
143 * Package visible for use by nested classes.
144 * @serial the comparator ordering this tree, or null
146 final Comparator comparator
;
149 * Class to represent an entry in the tree. Holds a single key-value pair,
150 * plus pointers to parent and child nodes.
152 * @author Eric Blake <ebb9@email.byu.edu>
154 private static final class Node
extends BasicMapEntry
156 // All fields package visible for use by nested classes.
157 /** The color of this node. */
160 /** The left child node. */
162 /** The right child node. */
164 /** The parent node. */
168 * Simple constructor.
170 * @param value the value
172 Node(Object key
, Object value
, int color
)
180 * Instantiate a new TreeMap with no elements, using the keys' natural
181 * ordering to sort. All entries in the map must have a key which implements
182 * Comparable, and which are <i>mutually comparable</i>, otherwise map
183 * operations may throw a {@link ClassCastException}. Attempts to use
184 * a null key will throw a {@link NullPointerException}.
190 this((Comparator
) null);
194 * Instantiate a new TreeMap with no elements, using the provided comparator
195 * to sort. All entries in the map must have keys which are mutually
196 * comparable by the Comparator, otherwise map operations may throw a
197 * {@link ClassCastException}.
199 * @param comparator the sort order for the keys of this map, or null
200 * for the natural order
202 public TreeMap(Comparator c
)
208 * Instantiate a new TreeMap, initializing it with all of the elements in
209 * the provided Map. The elements will be sorted using the natural
210 * ordering of the keys. This algorithm runs in n*log(n) time. All entries
211 * in the map must have keys which implement Comparable and are mutually
212 * comparable, otherwise map operations may throw a
213 * {@link ClassCastException}.
215 * @param map a Map, whose entries will be put into this TreeMap
216 * @throws ClassCastException if the keys in the provided Map are not
218 * @throws NullPointerException if map is null
221 public TreeMap(Map map
)
223 this((Comparator
) null);
228 * Instantiate a new TreeMap, initializing it with all of the elements in
229 * the provided SortedMap. The elements will be sorted using the same
230 * comparator as in the provided SortedMap. This runs in linear time.
232 * @param sm a SortedMap, whose entries will be put into this TreeMap
233 * @throws NullPointerException if sm is null
235 public TreeMap(SortedMap sm
)
237 this(sm
.comparator());
239 Iterator itr
= sm
.entrySet().iterator();
242 Node node
= firstNode();
246 Map
.Entry me
= (Map
.Entry
) itr
.next();
247 node
.key
= me
.getKey();
248 node
.value
= me
.getValue();
249 node
= successor(node
);
254 * Clears the Map so it has no keys. This is O(1).
267 * Returns a shallow clone of this TreeMap. The Map itself is cloned,
268 * but its contents are not.
272 public Object
clone()
277 copy
= (TreeMap
) super.clone();
279 catch (CloneNotSupportedException x
)
283 copy
.fabricateTree(size
);
285 Node node
= firstNode();
286 Node cnode
= copy
.firstNode();
290 cnode
.key
= node
.key
;
291 cnode
.value
= node
.value
;
292 node
= successor(node
);
293 cnode
= copy
.successor(cnode
);
299 * Return the comparator used to sort this map, or null if it is by
302 * @return the map's comparator
304 public Comparator
comparator()
310 * Returns true if the map contains a mapping for the given key.
312 * @param key the key to look for
313 * @return true if the key has a mapping
314 * @throws ClassCastException if key is not comparable to map elements
315 * @throws NullPointerException if key is null and the comparator is not
318 public boolean containsKey(Object key
)
320 return getNode(key
) != nil
;
324 * Returns true if the map contains at least one mapping to the given value.
325 * This requires linear time.
327 * @param value the value to look for
328 * @return true if the value appears in a mapping
330 public boolean containsValue(Object value
)
332 Node node
= firstNode();
335 if (equals(value
, node
.value
))
337 node
= successor(node
);
343 * Returns a "set view" of this TreeMap's entries. The set is backed by
344 * the TreeMap, so changes in one show up in the other. The set supports
345 * element removal, but not element addition.<p>
347 * Note that the iterators for all three views, from keySet(), entrySet(),
348 * and values(), traverse the TreeMap in sorted sequence.
350 * @return a set view of the entries
355 public Set
entrySet()
358 // Create an AbstractSet with custom implementations of those methods
359 // that can be overriden easily and efficiently.
360 entries
= new AbstractSet()
367 public Iterator
iterator()
369 return new TreeIterator(ENTRIES
);
374 TreeMap
.this.clear();
377 public boolean contains(Object o
)
379 if (! (o
instanceof Map
.Entry
))
381 Map
.Entry me
= (Map
.Entry
) o
;
382 Node n
= getNode(me
.getKey());
383 return n
!= nil
&& AbstractSet
.equals(me
.getValue(), n
.value
);
386 public boolean remove(Object o
)
388 if (! (o
instanceof Map
.Entry
))
390 Map
.Entry me
= (Map
.Entry
) o
;
391 Node n
= getNode(me
.getKey());
392 if (n
!= nil
&& AbstractSet
.equals(me
.getValue(), n
.value
))
404 * Returns the first (lowest) key in the map.
406 * @return the first key
407 * @throws NoSuchElementException if the map is empty
409 public Object
firstKey()
412 throw new NoSuchElementException();
413 return firstNode().key
;
417 * Return the value in this TreeMap associated with the supplied key,
418 * or <code>null</code> if the key maps to nothing. NOTE: Since the value
419 * could also be null, you must use containsKey to see if this key
420 * actually maps to something.
422 * @param key the key for which to fetch an associated value
423 * @return what the key maps to, if present
424 * @throws ClassCastException if key is not comparable to elements in the map
425 * @throws NullPointerException if key is null but the comparator does not
427 * @see #put(Object, Object)
428 * @see #containsKey(Object)
430 public Object
get(Object key
)
432 // Exploit fact that nil.value == null.
433 return getNode(key
).value
;
437 * Returns a view of this Map including all entries with keys less than
438 * <code>toKey</code>. The returned map is backed by the original, so changes
439 * in one appear in the other. The submap will throw an
440 * {@link IllegalArgumentException} for any attempt to access or add an
441 * element beyond the specified cutoff. The returned map does not include
442 * the endpoint; if you want inclusion, pass the successor element.
444 * @param toKey the (exclusive) cutoff point
445 * @return a view of the map less than the cutoff
446 * @throws ClassCastException if <code>toKey</code> is not compatible with
447 * the comparator (or is not Comparable, for natural ordering)
448 * @throws NullPointerException if toKey is null, but the comparator does not
449 * tolerate null elements
451 public SortedMap
headMap(Object toKey
)
453 return new SubMap(nil
, toKey
);
457 * Returns a "set view" of this TreeMap's keys. The set is backed by the
458 * TreeMap, so changes in one show up in the other. The set supports
459 * element removal, but not element addition.
461 * @return a set view of the keys
468 // Create an AbstractSet with custom implementations of those methods
469 // that can be overriden easily and efficiently.
470 keys
= new AbstractSet()
477 public Iterator
iterator()
479 return new TreeIterator(KEYS
);
484 TreeMap
.this.clear();
487 public boolean contains(Object o
)
489 return containsKey(o
);
492 public boolean remove(Object key
)
494 Node n
= getNode(key
);
505 * Returns the last (highest) key in the map.
507 * @return the last key
508 * @throws NoSuchElementException if the map is empty
510 public Object
lastKey()
513 throw new NoSuchElementException("empty");
514 return lastNode().key
;
518 * Puts the supplied value into the Map, mapped by the supplied key.
519 * The value may be retrieved by any object which <code>equals()</code>
520 * this key. NOTE: Since the prior value could also be null, you must
521 * first use containsKey if you want to see if you are replacing the
524 * @param key the key used to locate the value
525 * @param value the value to be stored in the HashMap
526 * @return the prior mapping of the key, or null if there was none
527 * @throws ClassCastException if key is not comparable to current map keys
528 * @throws NullPointerException if key is null, but the comparator does
531 * @see Object#equals(Object)
533 public Object
put(Object key
, Object value
)
539 // Find new node's parent.
540 while (current
!= nil
)
543 comparison
= compare(key
, current
.key
);
545 current
= current
.right
;
546 else if (comparison
< 0)
547 current
= current
.left
;
548 else // Key already in tree.
549 return current
.setValue(value
);
553 Node n
= new Node(key
, value
, RED
);
556 // Insert node in tree.
561 // Special case inserting into an empty tree.
570 // Rebalance after insert.
576 * Copies all elements of the given map into this hashtable. If this table
577 * already has a mapping for a key, the new mapping replaces the current
580 * @param m the map to be hashed into this
581 * @throws ClassCastException if a key in m is not comparable with keys
583 * @throws NullPointerException if a key in m is null, and the comparator
584 * does not tolerate nulls
586 public void putAll(Map m
)
588 Iterator itr
= m
.entrySet().iterator();
592 Map
.Entry e
= (Map
.Entry
) itr
.next();
593 put(e
.getKey(), e
.getValue());
598 * Removes from the TreeMap and returns the value which is mapped by the
599 * supplied key. If the key maps to nothing, then the TreeMap remains
600 * unchanged, and <code>null</code> is returned. NOTE: Since the value
601 * could also be null, you must use containsKey to see if you are
602 * actually removing a mapping.
604 * @param key the key used to locate the value to remove
605 * @return whatever the key mapped to, if present
606 * @throws ClassCastException if key is not comparable to current map keys
607 * @throws NullPointerException if key is null, but the comparator does
610 public Object
remove(Object key
)
612 Node n
= getNode(key
);
620 * Returns the number of key-value mappings currently in this Map.
630 * Returns a view of this Map including all entries with keys greater or
631 * equal to <code>fromKey</code> and less than <code>toKey</code> (a
632 * half-open interval). The returned map is backed by the original, so
633 * changes in one appear in the other. The submap will throw an
634 * {@link IllegalArgumentException} for any attempt to access or add an
635 * element beyond the specified cutoffs. The returned map includes the low
636 * endpoint but not the high; if you want to reverse this behavior on
637 * either end, pass in the successor element.
639 * @param fromKey the (inclusive) low cutoff point
640 * @param toKey the (exclusive) high cutoff point
641 * @return a view of the map between the cutoffs
642 * @throws ClassCastException if either cutoff is not compatible with
643 * the comparator (or is not Comparable, for natural ordering)
644 * @throws NullPointerException if fromKey or toKey is null, but the
645 * comparator does not tolerate null elements
646 * @throws IllegalArgumentException if fromKey is greater than toKey
648 public SortedMap
subMap(Object fromKey
, Object toKey
)
650 return new SubMap(fromKey
, toKey
);
654 * Returns a view of this Map including all entries with keys greater or
655 * equal to <code>fromKey</code>. The returned map is backed by the
656 * original, so changes in one appear in the other. The submap will throw an
657 * {@link IllegalArgumentException} for any attempt to access or add an
658 * element beyond the specified cutoff. The returned map includes the
659 * endpoint; if you want to exclude it, pass in the successor element.
661 * @param fromKey the (inclusive) low cutoff point
662 * @return a view of the map above the cutoff
663 * @throws ClassCastException if <code>fromKey</code> is not compatible with
664 * the comparator (or is not Comparable, for natural ordering)
665 * @throws NullPointerException if fromKey is null, but the comparator
666 * does not tolerate null elements
668 public SortedMap
tailMap(Object fromKey
)
670 return new SubMap(fromKey
, nil
);
674 * Returns a "collection view" (or "bag view") of this TreeMap's values.
675 * The collection is backed by the TreeMap, so changes in one show up
676 * in the other. The collection supports element removal, but not element
679 * @return a bag view of the values
683 public Collection
values()
686 // We don't bother overriding many of the optional methods, as doing so
687 // wouldn't provide any significant performance advantage.
688 values
= new AbstractCollection()
695 public Iterator
iterator()
697 return new TreeIterator(VALUES
);
702 TreeMap
.this.clear();
709 * Compares two elements by the set comparator, or by natural ordering.
710 * Package visible for use by nested classes.
712 * @param o1 the first object
713 * @param o2 the second object
714 * @throws ClassCastException if o1 and o2 are not mutually comparable,
715 * or are not Comparable with natural ordering
716 * @throws NullPointerException if o1 or o2 is null with natural ordering
718 final int compare(Object o1
, Object o2
)
720 return (comparator
== null
721 ?
((Comparable
) o1
).compareTo(o2
)
722 : comparator
.compare(o1
, o2
));
726 * Maintain red-black balance after deleting a node.
728 * @param node the child of the node just deleted, possibly nil
729 * @param parent the parent of the node just deleted, never nil
731 private void deleteFixup(Node node
, Node parent
)
733 // if (parent == nil)
734 // throw new InternalError();
735 // If a black node has been removed, we need to rebalance to avoid
736 // violating the "same number of black nodes on any path" rule. If
737 // node is red, we can simply recolor it black and all is well.
738 while (node
!= root
&& node
.color
== BLACK
)
740 if (node
== parent
.left
)
742 // Rebalance left side.
743 Node sibling
= parent
.right
;
744 // if (sibling == nil)
745 // throw new InternalError();
746 if (sibling
.color
== RED
)
748 // Case 1: Sibling is red.
749 // Recolor sibling and parent, and rotate parent left.
750 sibling
.color
= BLACK
;
753 sibling
= parent
.right
;
756 if (sibling
.left
.color
== BLACK
&& sibling
.right
.color
== BLACK
)
758 // Case 2: Sibling has no red children.
759 // Recolor sibling, and move to parent.
762 parent
= parent
.parent
;
766 if (sibling
.right
.color
== BLACK
)
768 // Case 3: Sibling has red left child.
769 // Recolor sibling and left child, rotate sibling right.
770 sibling
.left
.color
= BLACK
;
772 rotateRight(sibling
);
773 sibling
= parent
.right
;
775 // Case 4: Sibling has red right child. Recolor sibling,
776 // right child, and parent, and rotate parent left.
777 sibling
.color
= parent
.color
;
778 parent
.color
= BLACK
;
779 sibling
.right
.color
= BLACK
;
781 node
= root
; // Finished.
786 // Symmetric "mirror" of left-side case.
787 Node sibling
= parent
.left
;
788 // if (sibling == nil)
789 // throw new InternalError();
790 if (sibling
.color
== RED
)
792 // Case 1: Sibling is red.
793 // Recolor sibling and parent, and rotate parent right.
794 sibling
.color
= BLACK
;
797 sibling
= parent
.left
;
800 if (sibling
.right
.color
== BLACK
&& sibling
.left
.color
== BLACK
)
802 // Case 2: Sibling has no red children.
803 // Recolor sibling, and move to parent.
806 parent
= parent
.parent
;
810 if (sibling
.left
.color
== BLACK
)
812 // Case 3: Sibling has red right child.
813 // Recolor sibling and right child, rotate sibling left.
814 sibling
.right
.color
= BLACK
;
817 sibling
= parent
.left
;
819 // Case 4: Sibling has red left child. Recolor sibling,
820 // left child, and parent, and rotate parent right.
821 sibling
.color
= parent
.color
;
822 parent
.color
= BLACK
;
823 sibling
.left
.color
= BLACK
;
825 node
= root
; // Finished.
833 * Construct a perfectly balanced tree consisting of n "blank" nodes. This
834 * permits a tree to be generated from pre-sorted input in linear time.
836 * @param count the number of blank nodes, non-negative
838 private void fabricateTree(final int count
)
843 // We color every row of nodes black, except for the overflow nodes.
844 // I believe that this is the optimal arrangement. We construct the tree
845 // in place by temporarily linking each node to the next node in the row,
846 // then updating those links to the children when working on the next row.
848 // Make the root node.
849 root
= new Node(null, null, BLACK
);
854 // Fill each row that is completely full of nodes.
855 for (rowsize
= 2; rowsize
+ rowsize
< count
; rowsize
<<= 1)
859 for (int i
= 0; i
< rowsize
; i
+= 2)
861 Node left
= new Node(null, null, BLACK
);
862 Node right
= new Node(null, null, BLACK
);
863 left
.parent
= parent
;
865 right
.parent
= parent
;
867 Node next
= parent
.right
;
868 parent
.right
= right
;
877 // Now do the partial final row in red.
878 int overflow
= count
- rowsize
;
881 for (i
= 0; i
< overflow
; i
+= 2)
883 Node left
= new Node(null, null, RED
);
884 Node right
= new Node(null, null, RED
);
885 left
.parent
= parent
;
886 right
.parent
= parent
;
888 Node next
= parent
.right
;
889 parent
.right
= right
;
892 // Add a lone left node if necessary.
893 if (i
- overflow
== 0)
895 Node left
= new Node(null, null, RED
);
896 left
.parent
= parent
;
898 parent
= parent
.right
;
899 left
.parent
.right
= nil
;
901 // Unlink the remaining nodes of the previous row.
902 while (parent
!= nil
)
904 Node next
= parent
.right
;
911 * Returns the first sorted node in the map, or nil if empty. Package
912 * visible for use by nested classes.
914 * @return the first node
916 final Node
firstNode()
918 // Exploit fact that nil.left == nil.
920 while (node
.left
!= nil
)
926 * Return the TreeMap.Node associated with key, or the nil node if no such
927 * node exists in the tree. Package visible for use by nested classes.
929 * @param key the key to search for
930 * @return the node where the key is found, or nil
932 final Node
getNode(Object key
)
935 while (current
!= nil
)
937 int comparison
= compare(key
, current
.key
);
939 current
= current
.right
;
940 else if (comparison
< 0)
941 current
= current
.left
;
949 * Find the "highest" node which is < key. If key is nil, return last
950 * node. Package visible for use by nested classes.
952 * @param key the upper bound, exclusive
953 * @return the previous node
955 final Node
highestLessThan(Object key
)
964 while (current
!= nil
)
967 comparison
= compare(key
, current
.key
);
969 current
= current
.right
;
970 else if (comparison
< 0)
971 current
= current
.left
;
973 return predecessor(last
);
975 return comparison
<= 0 ?
predecessor(last
) : last
;
979 * Maintain red-black balance after inserting a new node.
981 * @param n the newly inserted node
983 private void insertFixup(Node n
)
985 // Only need to rebalance when parent is a RED node, and while at least
986 // 2 levels deep into the tree (ie: node has a grandparent). Remember
987 // that nil.color == BLACK.
988 while (n
.parent
.color
== RED
&& n
.parent
.parent
!= nil
)
990 if (n
.parent
== n
.parent
.parent
.left
)
992 Node uncle
= n
.parent
.parent
.right
;
993 // Uncle may be nil, in which case it is BLACK.
994 if (uncle
.color
== RED
)
996 // Case 1. Uncle is RED: Change colors of parent, uncle,
997 // and grandparent, and move n to grandparent.
998 n
.parent
.color
= BLACK
;
1000 uncle
.parent
.color
= RED
;
1005 if (n
== n
.parent
.right
)
1007 // Case 2. Uncle is BLACK and x is right child.
1008 // Move n to parent, and rotate n left.
1012 // Case 3. Uncle is BLACK and x is left child.
1013 // Recolor parent, grandparent, and rotate grandparent right.
1014 n
.parent
.color
= BLACK
;
1015 n
.parent
.parent
.color
= RED
;
1016 rotateRight(n
.parent
.parent
);
1021 // Mirror image of above code.
1022 Node uncle
= n
.parent
.parent
.left
;
1023 // Uncle may be nil, in which case it is BLACK.
1024 if (uncle
.color
== RED
)
1026 // Case 1. Uncle is RED: Change colors of parent, uncle,
1027 // and grandparent, and move n to grandparent.
1028 n
.parent
.color
= BLACK
;
1029 uncle
.color
= BLACK
;
1030 uncle
.parent
.color
= RED
;
1035 if (n
== n
.parent
.left
)
1037 // Case 2. Uncle is BLACK and x is left child.
1038 // Move n to parent, and rotate n right.
1042 // Case 3. Uncle is BLACK and x is right child.
1043 // Recolor parent, grandparent, and rotate grandparent left.
1044 n
.parent
.color
= BLACK
;
1045 n
.parent
.parent
.color
= RED
;
1046 rotateLeft(n
.parent
.parent
);
1054 * Returns the last sorted node in the map, or nil if empty.
1056 * @return the last node
1058 private Node
lastNode()
1060 // Exploit fact that nil.right == nil.
1062 while (node
.right
!= nil
)
1068 * Find the "lowest" node which is >= key. If key is nil, return either
1069 * nil or the first node, depending on the parameter first.
1070 * Package visible for use by nested classes.
1072 * @param key the lower bound, inclusive
1073 * @param first true to return the first element instead of nil for nil key
1074 * @return the next node
1076 final Node
lowestGreaterThan(Object key
, boolean first
)
1079 return first ?
firstNode() : nil
;
1082 Node current
= root
;
1085 while (current
!= nil
)
1088 comparison
= compare(key
, current
.key
);
1090 current
= current
.right
;
1091 else if (comparison
< 0)
1092 current
= current
.left
;
1096 return comparison
> 0 ?
successor(last
) : last
;
1100 * Return the node preceding the given one, or nil if there isn't one.
1102 * @param node the current node, not nil
1103 * @return the prior node in sorted order
1105 private Node
predecessor(Node node
)
1107 if (node
.left
!= nil
)
1110 while (node
.right
!= nil
)
1115 Node parent
= node
.parent
;
1116 // Exploit fact that nil.left == nil and node is non-nil.
1117 while (node
== parent
.left
)
1120 parent
= node
.parent
;
1126 * Construct a tree from sorted keys in linear time. Package visible for
1129 * @param s the stream to read from
1130 * @param count the number of keys to read
1131 * @param readValue true to read values, false to insert "" as the value
1132 * @throws ClassNotFoundException if the underlying stream fails
1133 * @throws IOException if the underlying stream fails
1134 * @see #readObject(ObjectInputStream)
1135 * @see TreeSet#readObject(ObjectInputStream)
1137 final void putFromObjStream(ObjectInputStream s
, int count
,
1139 throws IOException
, ClassNotFoundException
1141 fabricateTree(count
);
1142 Node node
= firstNode();
1144 while (--count
>= 0)
1146 node
.key
= s
.readObject();
1147 node
.value
= readValues ? s
.readObject() : "";
1148 node
= successor(node
);
1153 * Construct a tree from sorted keys in linear time, with values of "".
1154 * Package visible for use by TreeSet.
1156 * @param keys the iterator over the sorted keys
1157 * @param count the number of nodes to insert
1158 * @see TreeSet#TreeSet(SortedSet)
1160 final void putKeysLinear(Iterator keys
, int count
)
1162 fabricateTree(count
);
1163 Node node
= firstNode();
1165 while (--count
>= 0)
1167 node
.key
= keys
.next();
1169 node
= successor(node
);
1174 * Deserializes this object from the given stream.
1176 * @param s the stream to read from
1177 * @throws ClassNotFoundException if the underlying stream fails
1178 * @throws IOException if the underlying stream fails
1179 * @serialData the <i>size</i> (int), followed by key (Object) and value
1180 * (Object) pairs in sorted order
1182 private void readObject(ObjectInputStream s
)
1183 throws IOException
, ClassNotFoundException
1185 s
.defaultReadObject();
1186 int size
= s
.readInt();
1187 putFromObjStream(s
, size
, true);
1191 * Remove node from tree. This will increment modCount and decrement size.
1192 * Node must exist in the tree. Package visible for use by nested classes.
1194 * @param node the node to remove
1196 final void removeNode(Node node
)
1204 // Find splice, the node at the position to actually remove from the tree.
1205 if (node
.left
== nil
)
1207 // Node to be deleted has 0 or 1 children.
1211 else if (node
.right
== nil
)
1213 // Node to be deleted has 1 child.
1219 // Node has 2 children. Splice is node's predecessor, and we swap
1220 // its contents into node.
1222 while (splice
.right
!= nil
)
1223 splice
= splice
.right
;
1224 child
= splice
.left
;
1225 node
.key
= splice
.key
;
1226 node
.value
= splice
.value
;
1229 // Unlink splice from the tree.
1230 Node parent
= splice
.parent
;
1232 child
.parent
= parent
;
1235 // Special case for 0 or 1 node remaining.
1239 if (splice
== parent
.left
)
1240 parent
.left
= child
;
1242 parent
.right
= child
;
1244 if (splice
.color
== BLACK
)
1245 deleteFixup(child
, parent
);
1249 * Rotate node n to the left.
1251 * @param node the node to rotate
1253 private void rotateLeft(Node node
)
1255 Node child
= node
.right
;
1256 // if (node == nil || child == nil)
1257 // throw new InternalError();
1259 // Establish node.right link.
1260 node
.right
= child
.left
;
1261 if (child
.left
!= nil
)
1262 child
.left
.parent
= node
;
1264 // Establish child->parent link.
1265 child
.parent
= node
.parent
;
1266 if (node
.parent
!= nil
)
1268 if (node
== node
.parent
.left
)
1269 node
.parent
.left
= child
;
1271 node
.parent
.right
= child
;
1276 // Link n and child.
1278 node
.parent
= child
;
1282 * Rotate node n to the right.
1284 * @param node the node to rotate
1286 private void rotateRight(Node node
)
1288 Node child
= node
.left
;
1289 // if (node == nil || child == nil)
1290 // throw new InternalError();
1292 // Establish node.left link.
1293 node
.left
= child
.right
;
1294 if (child
.right
!= nil
)
1295 child
.right
.parent
= node
;
1297 // Establish child->parent link.
1298 child
.parent
= node
.parent
;
1299 if (node
.parent
!= nil
)
1301 if (node
== node
.parent
.right
)
1302 node
.parent
.right
= child
;
1304 node
.parent
.left
= child
;
1309 // Link n and child.
1311 node
.parent
= child
;
1315 * Return the node following the given one, or nil if there isn't one.
1316 * Package visible for use by nested classes.
1318 * @param node the current node, not nil
1319 * @return the next node in sorted order
1321 final Node
successor(Node node
)
1323 if (node
.right
!= nil
)
1326 while (node
.left
!= nil
)
1331 Node parent
= node
.parent
;
1332 // Exploit fact that nil.right == nil and node is non-nil.
1333 while (node
== parent
.right
)
1336 parent
= parent
.parent
;
1342 * Serializes this object to the given stream.
1344 * @param s the stream to write to
1345 * @throws IOException if the underlying stream fails
1346 * @serialData the <i>size</i> (int), followed by key (Object) and value
1347 * (Object) pairs in sorted order
1349 private void writeObject(ObjectOutputStream s
) throws IOException
1351 s
.defaultWriteObject();
1353 Node node
= firstNode();
1357 s
.writeObject(node
.key
);
1358 s
.writeObject(node
.value
);
1359 node
= successor(node
);
1364 * Iterate over HashMap's entries. This implementation is parameterized
1365 * to give a sequential view of keys, values, or entries.
1367 * @author Eric Blake <ebb9@email.byu.edu>
1369 private final class TreeIterator
implements Iterator
1372 * The type of this Iterator: {@link #KEYS}, {@link #VALUES},
1373 * or {@link #ENTRIES}.
1375 private final int type
;
1376 /** The number of modifications to the backing Map that we know about. */
1377 private int knownMod
= modCount
;
1378 /** The last Entry returned by a next() call. */
1380 /** The next entry that should be returned by next(). */
1383 * The last node visible to this iterator. This is used when iterating
1386 private final Node max
;
1389 * Construct a new TreeIterator with the supplied type.
1390 * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES}
1392 TreeIterator(int type
)
1394 // FIXME gcj cannot handle this. Bug java/4695
1395 // this(type, firstNode(), nil);
1397 this.next
= firstNode();
1402 * Construct a new TreeIterator with the supplied type. Iteration will
1403 * be from "first" (inclusive) to "max" (exclusive).
1405 * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES}
1406 * @param first where to start iteration, nil for empty iterator
1407 * @param max the cutoff for iteration, nil for all remaining nodes
1409 TreeIterator(int type
, Node first
, Node max
)
1417 * Returns true if the Iterator has more elements.
1418 * @return true if there are more elements
1419 * @throws ConcurrentModificationException if the TreeMap was modified
1421 public boolean hasNext()
1423 if (knownMod
!= modCount
)
1424 throw new ConcurrentModificationException();
1429 * Returns the next element in the Iterator's sequential view.
1430 * @return the next element
1431 * @throws ConcurrentModificationException if the TreeMap was modified
1432 * @throws NoSuchElementException if there is none
1434 public Object
next()
1436 if (knownMod
!= modCount
)
1437 throw new ConcurrentModificationException();
1439 throw new NoSuchElementException();
1441 next
= successor(last
);
1445 else if (type
== KEYS
)
1451 * Removes from the backing TreeMap the last element which was fetched
1452 * with the <code>next()</code> method.
1453 * @throws ConcurrentModificationException if the TreeMap was modified
1454 * @throws IllegalStateException if called when there is no last element
1456 public void remove()
1458 if (knownMod
!= modCount
)
1459 throw new ConcurrentModificationException();
1461 throw new IllegalStateException();
1467 } // class TreeIterator
1470 * Implementation of {@link #subMap(Object, Object)} and other map
1471 * ranges. This class provides a view of a portion of the original backing
1472 * map, and throws {@link IllegalArgumentException} for attempts to
1473 * access beyond that range.
1475 * @author Eric Blake <ebb9@email.byu.edu>
1477 private final class SubMap
extends AbstractMap
implements SortedMap
1480 * The lower range of this view, inclusive, or nil for unbounded.
1481 * Package visible for use by nested classes.
1483 final Object minKey
;
1486 * The upper range of this view, exclusive, or nil for unbounded.
1487 * Package visible for use by nested classes.
1489 final Object maxKey
;
1492 * The cache for {@link #entrySet()}.
1494 private Set entries
;
1497 * Create a SubMap representing the elements between minKey (inclusive)
1498 * and maxKey (exclusive). If minKey is nil, SubMap has no lower bound
1499 * (headMap). If maxKey is nil, the SubMap has no upper bound (tailMap).
1501 * @param minKey the lower bound
1502 * @param maxKey the upper bound
1503 * @throws IllegalArgumentException if minKey > maxKey
1505 SubMap(Object minKey
, Object maxKey
)
1507 if (minKey
!= nil
&& maxKey
!= nil
&& compare(minKey
, maxKey
) > 0)
1508 throw new IllegalArgumentException("fromKey > toKey");
1509 this.minKey
= minKey
;
1510 this.maxKey
= maxKey
;
1514 * Check if "key" is in within the range bounds for this SubMap. The
1515 * lower ("from") SubMap range is inclusive, and the upper ("to") bound
1516 * is exclusive. Package visible for use by nested classes.
1518 * @param key the key to check
1519 * @return true if the key is in range
1521 final boolean keyInRange(Object key
)
1523 return ((minKey
== nil
|| compare(key
, minKey
) >= 0)
1524 && (maxKey
== nil
|| compare(key
, maxKey
) < 0));
1529 Node next
= lowestGreaterThan(minKey
, true);
1530 Node max
= lowestGreaterThan(maxKey
, false);
1533 Node current
= next
;
1534 next
= successor(current
);
1535 removeNode(current
);
1539 public Comparator
comparator()
1544 public boolean containsKey(Object key
)
1546 return keyInRange(key
) && TreeMap
.this.containsKey(key
);
1549 public boolean containsValue(Object value
)
1551 Node node
= lowestGreaterThan(minKey
, true);
1552 Node max
= lowestGreaterThan(maxKey
, false);
1555 if (equals(value
, node
.getValue()))
1557 node
= successor(node
);
1562 public Set
entrySet()
1564 if (entries
== null)
1565 // Create an AbstractSet with custom implementations of those methods
1566 // that can be overriden easily and efficiently.
1567 entries
= new AbstractSet()
1571 return SubMap
.this.size();
1574 public Iterator
iterator()
1576 Node first
= lowestGreaterThan(minKey
, true);
1577 Node max
= lowestGreaterThan(maxKey
, false);
1578 return new TreeIterator(ENTRIES
, first
, max
);
1583 SubMap
.this.clear();
1586 public boolean contains(Object o
)
1588 if (! (o
instanceof Map
.Entry
))
1590 Map
.Entry me
= (Map
.Entry
) o
;
1591 Object key
= me
.getKey();
1592 if (! keyInRange(key
))
1594 Node n
= getNode(key
);
1595 return n
!= nil
&& AbstractSet
.equals(me
.getValue(), n
.value
);
1598 public boolean remove(Object o
)
1600 if (! (o
instanceof Map
.Entry
))
1602 Map
.Entry me
= (Map
.Entry
) o
;
1603 Object key
= me
.getKey();
1604 if (! keyInRange(key
))
1606 Node n
= getNode(key
);
1607 if (n
!= nil
&& AbstractSet
.equals(me
.getValue(), n
.value
))
1618 public Object
firstKey()
1620 Node node
= lowestGreaterThan(minKey
, true);
1621 if (node
== nil
|| ! keyInRange(node
.key
))
1622 throw new NoSuchElementException();
1626 public Object
get(Object key
)
1628 if (keyInRange(key
))
1629 return TreeMap
.this.get(key
);
1633 public SortedMap
headMap(Object toKey
)
1635 if (! keyInRange(toKey
))
1636 throw new IllegalArgumentException("key outside range");
1637 return new SubMap(minKey
, toKey
);
1642 if (this.keys
== null)
1643 // Create an AbstractSet with custom implementations of those methods
1644 // that can be overriden easily and efficiently.
1645 this.keys
= new AbstractSet()
1649 return SubMap
.this.size();
1652 public Iterator
iterator()
1654 Node first
= lowestGreaterThan(minKey
, true);
1655 Node max
= lowestGreaterThan(maxKey
, false);
1656 return new TreeIterator(KEYS
, first
, max
);
1661 SubMap
.this.clear();
1664 public boolean contains(Object o
)
1666 if (! keyInRange(o
))
1668 return getNode(o
) != nil
;
1671 public boolean remove(Object o
)
1673 if (! keyInRange(o
))
1675 Node n
= getNode(o
);
1687 public Object
lastKey()
1689 Node node
= highestLessThan(maxKey
);
1690 if (node
== nil
|| ! keyInRange(node
.key
))
1691 throw new NoSuchElementException();
1695 public Object
put(Object key
, Object value
)
1697 if (! keyInRange(key
))
1698 throw new IllegalArgumentException("Key outside range");
1699 return TreeMap
.this.put(key
, value
);
1702 public Object
remove(Object key
)
1704 if (keyInRange(key
))
1705 return TreeMap
.this.remove(key
);
1711 Node node
= lowestGreaterThan(minKey
, true);
1712 Node max
= lowestGreaterThan(maxKey
, false);
1717 node
= successor(node
);
1722 public SortedMap
subMap(Object fromKey
, Object toKey
)
1724 if (! keyInRange(fromKey
) || ! keyInRange(toKey
))
1725 throw new IllegalArgumentException("key outside range");
1726 return new SubMap(fromKey
, toKey
);
1729 public SortedMap
tailMap(Object fromKey
)
1731 if (! keyInRange(fromKey
))
1732 throw new IllegalArgumentException("key outside range");
1733 return new SubMap(fromKey
, maxKey
);
1736 public Collection
values()
1738 if (this.values
== null)
1739 // Create an AbstractCollection with custom implementations of those
1740 // methods that can be overriden easily and efficiently.
1741 this.values
= new AbstractCollection()
1745 return SubMap
.this.size();
1748 public Iterator
iterator()
1750 Node first
= lowestGreaterThan(minKey
, true);
1751 Node max
= lowestGreaterThan(maxKey
, false);
1752 return new TreeIterator(VALUES
, first
, max
);
1757 SubMap
.this.clear();