home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / util / TreeMap.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  37.4 KB  |  1,289 lines

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