Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package java.util;
     18 
     19 import java.io.IOException;
     20 import java.io.ObjectInputStream;
     21 import java.io.ObjectInputStream.GetField;
     22 import java.io.ObjectOutputStream;
     23 import java.io.ObjectStreamException;
     24 import java.io.Serializable;
     25 import static java.util.TreeMap.Bound.*;
     26 import static java.util.TreeMap.Relation.*;
     27 import libcore.util.Objects;
     28 
     29 /**
     30  * A map whose entries are sorted by their keys. All optional operations such as
     31  * {@link #put} and {@link #remove} are supported.
     32  *
     33  * <p>This map sorts keys using either a user-supplied comparator or the key's
     34  * natural order:
     35  * <ul>
     36  *   <li>User supplied comparators must be able to compare any pair of keys in
     37  *       this map. If a user-supplied comparator is in use, it will be returned
     38  *       by {@link #comparator}.
     39  *   <li>If no user-supplied comparator is supplied, keys will be sorted by
     40  *       their natural order. Keys must be <i>mutually comparable</i>: they must
     41  *       implement {@link Comparable} and {@link Comparable#compareTo
     42  *       compareTo()} must be able to compare each key with any other key in
     43  *       this map. In this case {@link #comparator} will return null.
     44  * </ul>
     45  * With either a comparator or a natural ordering, comparisons should be
     46  * <i>consistent with equals</i>. An ordering is consistent with equals if for
     47  * every pair of keys {@code a} and {@code b}, {@code a.equals(b)} if and only
     48  * if {@code compare(a, b) == 0}.
     49  *
     50  * <p>When the ordering is not consistent with equals the behavior of this
     51  * class is well defined but does not honor the contract specified by {@link
     52  * Map}. Consider a tree map of case-insensitive strings, an ordering that is
     53  * not consistent with equals: <pre>   {@code
     54  *   TreeMap<String, String> map = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
     55  *   map.put("a", "android");
     56  *
     57  *   // The Map API specifies that the next line should print "null" because
     58  *   // "a".equals("A") is false and there is no mapping for upper case "A".
     59  *   // But the case insensitive ordering says compare("a", "A") == 0. TreeMap
     60  *   // uses only comparators/comparable on keys and so this prints "android".
     61  *   System.out.println(map.get("A"));
     62  * }</pre>
     63  *
     64  * @since 1.2
     65  */
     66 public class TreeMap<K, V> extends AbstractMap<K, V>
     67         implements SortedMap<K, V>, NavigableMap<K, V>, Cloneable, Serializable {
     68 
     69     @SuppressWarnings("unchecked") // to avoid Comparable<Comparable<Comparable<...>>>
     70     private static final Comparator<Comparable> NATURAL_ORDER = new Comparator<Comparable>() {
     71         public int compare(Comparable a, Comparable b) {
     72             return a.compareTo(b);
     73         }
     74     };
     75 
     76     Comparator<? super K> comparator;
     77     Node<K, V> root;
     78     int size = 0;
     79     int modCount = 0;
     80 
     81     /**
     82      * Create a natural order, empty tree map whose keys must be mutually
     83      * comparable and non-null.
     84      */
     85     @SuppressWarnings("unchecked") // unsafe! this assumes K is comparable
     86     public TreeMap() {
     87         this.comparator = (Comparator<? super K>) NATURAL_ORDER;
     88     }
     89 
     90     /**
     91      * Create a natural order tree map populated with the key/value pairs of
     92      * {@code copyFrom}. This map's keys must be mutually comparable and
     93      * non-null.
     94      *
     95      * <p>Even if {@code copyFrom} is a {@code SortedMap}, the constructed map
     96      * <strong>will not</strong> use {@code copyFrom}'s ordering. This
     97      * constructor always creates a naturally-ordered map. Because the {@code
     98      * TreeMap} constructor overloads are ambiguous, prefer to construct a map
     99      * and populate it in two steps: <pre>   {@code
    100      *   TreeMap<String, Integer> customOrderedMap
    101      *       = new TreeMap<String, Integer>(copyFrom.comparator());
    102      *   customOrderedMap.putAll(copyFrom);
    103      * }</pre>
    104      */
    105     public TreeMap(Map<? extends K, ? extends V> copyFrom) {
    106         this();
    107         for (Map.Entry<? extends K, ? extends V> entry : copyFrom.entrySet()) {
    108             putInternal(entry.getKey(), entry.getValue());
    109         }
    110     }
    111 
    112     /**
    113      * Create a tree map ordered by {@code comparator}. This map's keys may only
    114      * be null if {@code comparator} permits.
    115      *
    116      * @param comparator the comparator to order elements with, or {@code null} to use the natural
    117      * ordering.
    118      */
    119     @SuppressWarnings("unchecked") // unsafe! if comparator is null, this assumes K is comparable
    120     public TreeMap(Comparator<? super K> comparator) {
    121         if (comparator != null) {
    122             this.comparator = comparator;
    123         } else {
    124             this.comparator = (Comparator<? super K>) NATURAL_ORDER;
    125         }
    126     }
    127 
    128     /**
    129      * Create a tree map with the ordering and key/value pairs of {@code
    130      * copyFrom}. This map's keys may only be null if the {@code copyFrom}'s
    131      * ordering permits.
    132      *
    133      * <p>The constructed map <strong>will always use</strong> {@code
    134      * copyFrom}'s ordering. Because the {@code TreeMap} constructor overloads
    135      * are ambigous, prefer to construct a map and populate it in two steps:
    136      * <pre>   {@code
    137      *   TreeMap<String, Integer> customOrderedMap
    138      *       = new TreeMap<String, Integer>(copyFrom.comparator());
    139      *   customOrderedMap.putAll(copyFrom);
    140      * }</pre>
    141      */
    142     @SuppressWarnings("unchecked") // if copyFrom's keys are comparable this map's keys must be also
    143     public TreeMap(SortedMap<K, ? extends V> copyFrom) {
    144         Comparator<? super K> sourceComparator = copyFrom.comparator();
    145         if (sourceComparator != null) {
    146             this.comparator = sourceComparator;
    147         } else {
    148             this.comparator = (Comparator<? super K>) NATURAL_ORDER;
    149         }
    150         for (Map.Entry<K, ? extends V> entry : copyFrom.entrySet()) {
    151             putInternal(entry.getKey(), entry.getValue());
    152         }
    153     }
    154 
    155     @Override public Object clone() {
    156         try {
    157             @SuppressWarnings("unchecked") // super.clone() must return the same type
    158             TreeMap<K, V> map = (TreeMap<K, V>) super.clone();
    159             map.root = root != null ? root.copy(null) : null;
    160             map.entrySet = null;
    161             map.keySet = null;
    162             return map;
    163         } catch (CloneNotSupportedException e) {
    164             throw new AssertionError();
    165         }
    166     }
    167 
    168     @Override public int size() {
    169         return size;
    170     }
    171 
    172     @Override public boolean isEmpty() {
    173         return size == 0;
    174     }
    175 
    176     @Override public V get(Object key) {
    177         Entry<K, V> entry = findByObject(key);
    178         return entry != null ? entry.getValue() : null;
    179     }
    180 
    181     @Override public boolean containsKey(Object key) {
    182         return findByObject(key) != null;
    183     }
    184 
    185     @Override public V put(K key, V value) {
    186         return putInternal(key, value);
    187     }
    188 
    189     @Override public void clear() {
    190         root = null;
    191         size = 0;
    192         modCount++;
    193     }
    194 
    195     @Override public V remove(Object key) {
    196         Node<K, V> node = removeInternalByKey(key);
    197         return node != null ? node.value : null;
    198     }
    199 
    200     /*
    201      * AVL methods
    202      */
    203 
    204     enum Relation {
    205         LOWER,
    206         FLOOR,
    207         EQUAL,
    208         CREATE,
    209         CEILING,
    210         HIGHER;
    211 
    212         /**
    213          * Returns a possibly-flipped relation for use in descending views.
    214          *
    215          * @param ascending false to flip; true to return this.
    216          */
    217         Relation forOrder(boolean ascending) {
    218             if (ascending) {
    219                 return this;
    220             }
    221 
    222             switch (this) {
    223                 case LOWER:
    224                     return HIGHER;
    225                 case FLOOR:
    226                     return CEILING;
    227                 case EQUAL:
    228                     return EQUAL;
    229                 case CEILING:
    230                     return FLOOR;
    231                 case HIGHER:
    232                     return LOWER;
    233                 default:
    234                     throw new IllegalStateException();
    235             }
    236         }
    237     }
    238 
    239     V putInternal(K key, V value) {
    240         Node<K, V> created = find(key, Relation.CREATE);
    241         V result = created.value;
    242         created.value = value;
    243         return result;
    244     }
    245 
    246     /**
    247      * Returns the node at or adjacent to the given key, creating it if requested.
    248      *
    249      * @throws ClassCastException if {@code key} and the tree's keys aren't mutually comparable.
    250      */
    251     Node<K, V> find(K key, Relation relation) {
    252         if (root == null) {
    253             if (comparator == NATURAL_ORDER && !(key instanceof Comparable)) {
    254                 throw new ClassCastException(key.getClass().getName() + " is not Comparable"); // NullPointerException ok
    255             }
    256             if (relation == Relation.CREATE) {
    257                 root = new Node<K, V>(null, key);
    258                 size = 1;
    259                 modCount++;
    260                 return root;
    261             } else {
    262                 return null;
    263             }
    264         }
    265 
    266         /*
    267          * Micro-optimization: avoid polymorphic calls to Comparator.compare().
    268          * This is 10% faster for naturally ordered trees.
    269          */
    270         @SuppressWarnings("unchecked") // will throw a ClassCastException below if there's trouble
    271         Comparable<Object> comparableKey = (comparator == NATURAL_ORDER)
    272                 ? (Comparable<Object>) key
    273                 : null;
    274 
    275         Node<K, V> nearest = root;
    276         while (true) {
    277             int comparison = (comparableKey != null)
    278                     ? comparableKey.compareTo(nearest.key)
    279                     : comparator.compare(key, nearest.key);
    280 
    281             /*
    282              * We found the requested key.
    283              */
    284             if (comparison == 0) {
    285                 switch (relation) {
    286                     case LOWER:
    287                         return nearest.prev();
    288                     case FLOOR:
    289                     case EQUAL:
    290                     case CREATE:
    291                     case CEILING:
    292                         return nearest;
    293                     case HIGHER:
    294                         return nearest.next();
    295                 }
    296             }
    297 
    298             Node<K, V> child = (comparison < 0) ? nearest.left : nearest.right;
    299             if (child != null) {
    300                 nearest = child;
    301                 continue;
    302             }
    303 
    304             /*
    305              * We found a nearest node. Every key not in the tree has up to two
    306              * nearest nodes, one lower and one higher.
    307              */
    308 
    309             if (comparison < 0) { // nearest.key is higher
    310                 switch (relation) {
    311                     case LOWER:
    312                     case FLOOR:
    313                         return nearest.prev();
    314                     case CEILING:
    315                     case HIGHER:
    316                         return nearest;
    317                     case EQUAL:
    318                         return null;
    319                     case CREATE:
    320                         Node<K, V> created = new Node<K, V>(nearest, key);
    321                         nearest.left = created;
    322                         size++;
    323                         modCount++;
    324                         rebalance(nearest, true);
    325                         return created;
    326                 }
    327             } else { // comparison > 0, nearest.key is lower
    328                 switch (relation) {
    329                     case LOWER:
    330                     case FLOOR:
    331                         return nearest;
    332                     case CEILING:
    333                     case HIGHER:
    334                         return nearest.next();
    335                     case EQUAL:
    336                         return null;
    337                     case CREATE:
    338                         Node<K, V> created = new Node<K, V>(nearest, key);
    339                         nearest.right = created;
    340                         size++;
    341                         modCount++;
    342                         rebalance(nearest, true);
    343                         return created;
    344                 }
    345             }
    346         }
    347     }
    348 
    349     @SuppressWarnings("unchecked") // this method throws ClassCastExceptions!
    350     Node<K, V> findByObject(Object key) {
    351         return find((K) key, EQUAL);
    352     }
    353 
    354     /**
    355      * Returns this map's entry that has the same key and value as {@code
    356      * entry}, or null if this map has no such entry.
    357      *
    358      * <p>This method uses the comparator for key equality rather than {@code
    359      * equals}. If this map's comparator isn't consistent with equals (such as
    360      * {@code String.CASE_INSENSITIVE_ORDER}), then {@code remove()} and {@code
    361      * contains()} will violate the collections API.
    362      */
    363     Node<K, V> findByEntry(Entry<?, ?> entry) {
    364         Node<K, V> mine = findByObject(entry.getKey());
    365         boolean valuesEqual = mine != null && Objects.equal(mine.value, entry.getValue());
    366         return valuesEqual ? mine : null;
    367     }
    368 
    369     /**
    370      * Removes {@code node} from this tree, rearranging the tree's structure as
    371      * necessary.
    372      */
    373     void removeInternal(Node<K, V> node) {
    374         Node<K, V> left = node.left;
    375         Node<K, V> right = node.right;
    376         Node<K, V> originalParent = node.parent;
    377         if (left != null && right != null) {
    378 
    379             /*
    380              * To remove a node with both left and right subtrees, move an
    381              * adjacent node from one of those subtrees into this node's place.
    382              *
    383              * Removing the adjacent node may change this node's subtrees. This
    384              * node may no longer have two subtrees once the adjacent node is
    385              * gone!
    386              */
    387 
    388             Node<K, V> adjacent = (left.height > right.height) ? left.last() : right.first();
    389             removeInternal(adjacent); // takes care of rebalance and size--
    390 
    391             int leftHeight = 0;
    392             left = node.left;
    393             if (left != null) {
    394                 leftHeight = left.height;
    395                 adjacent.left = left;
    396                 left.parent = adjacent;
    397                 node.left = null;
    398             }
    399             int rightHeight = 0;
    400             right = node.right;
    401             if (right != null) {
    402                 rightHeight = right.height;
    403                 adjacent.right = right;
    404                 right.parent = adjacent;
    405                 node.right = null;
    406             }
    407             adjacent.height = Math.max(leftHeight, rightHeight) + 1;
    408             replaceInParent(node, adjacent);
    409             return;
    410         } else if (left != null) {
    411             replaceInParent(node, left);
    412             node.left = null;
    413         } else if (right != null) {
    414             replaceInParent(node, right);
    415             node.right = null;
    416         } else {
    417             replaceInParent(node, null);
    418         }
    419 
    420         rebalance(originalParent, false);
    421         size--;
    422         modCount++;
    423     }
    424 
    425     Node<K, V> removeInternalByKey(Object key) {
    426         Node<K, V> node = findByObject(key);
    427         if (node != null) {
    428             removeInternal(node);
    429         }
    430         return node;
    431     }
    432 
    433     private void replaceInParent(Node<K, V> node, Node<K, V> replacement) {
    434         Node<K, V> parent = node.parent;
    435         node.parent = null;
    436         if (replacement != null) {
    437             replacement.parent = parent;
    438         }
    439 
    440         if (parent != null) {
    441             if (parent.left == node) {
    442                 parent.left = replacement;
    443             } else {
    444                 assert (parent.right == node);
    445                 parent.right = replacement;
    446             }
    447         } else {
    448             root = replacement;
    449         }
    450     }
    451 
    452     /**
    453      * Rebalances the tree by making any AVL rotations necessary between the
    454      * newly-unbalanced node and the tree's root.
    455      *
    456      * @param insert true if the node was unbalanced by an insert; false if it
    457      *     was by a removal.
    458      */
    459     private void rebalance(Node<K, V> unbalanced, boolean insert) {
    460         for (Node<K, V> node = unbalanced; node != null; node = node.parent) {
    461             Node<K, V> left = node.left;
    462             Node<K, V> right = node.right;
    463             int leftHeight = left != null ? left.height : 0;
    464             int rightHeight = right != null ? right.height : 0;
    465 
    466             int delta = leftHeight - rightHeight;
    467             if (delta == -2) {
    468                 Node<K, V> rightLeft = right.left;
    469                 Node<K, V> rightRight = right.right;
    470                 int rightRightHeight = rightRight != null ? rightRight.height : 0;
    471                 int rightLeftHeight = rightLeft != null ? rightLeft.height : 0;
    472 
    473                 int rightDelta = rightLeftHeight - rightRightHeight;
    474                 if (rightDelta == -1 || (rightDelta == 0 && !insert)) {
    475                     rotateLeft(node); // AVL right right
    476                 } else {
    477                     assert (rightDelta == 1);
    478                     rotateRight(right); // AVL right left
    479                     rotateLeft(node);
    480                 }
    481                 if (insert) {
    482                     break; // no further rotations will be necessary
    483                 }
    484 
    485             } else if (delta == 2) {
    486                 Node<K, V> leftLeft = left.left;
    487                 Node<K, V> leftRight = left.right;
    488                 int leftRightHeight = leftRight != null ? leftRight.height : 0;
    489                 int leftLeftHeight = leftLeft != null ? leftLeft.height : 0;
    490 
    491                 int leftDelta = leftLeftHeight - leftRightHeight;
    492                 if (leftDelta == 1 || (leftDelta == 0 && !insert)) {
    493                     rotateRight(node); // AVL left left
    494                 } else {
    495                     assert (leftDelta == -1);
    496                     rotateLeft(left); // AVL left right
    497                     rotateRight(node);
    498                 }
    499                 if (insert) {
    500                     break; // no further rotations will be necessary
    501                 }
    502 
    503             } else if (delta == 0) {
    504                 node.height = leftHeight + 1; // leftHeight == rightHeight
    505                 if (insert) {
    506                     break; // the insert caused balance, so rebalancing is done!
    507                 }
    508 
    509             } else {
    510                 assert (delta == -1 || delta == 1);
    511                 node.height = Math.max(leftHeight, rightHeight) + 1;
    512                 if (!insert) {
    513                     break; // the height hasn't changed, so rebalancing is done!
    514                 }
    515             }
    516         }
    517     }
    518 
    519     /**
    520      * Rotates the subtree so that its root's right child is the new root.
    521      */
    522     private void rotateLeft(Node<K, V> root) {
    523         Node<K, V> left = root.left;
    524         Node<K, V> pivot = root.right;
    525         Node<K, V> pivotLeft = pivot.left;
    526         Node<K, V> pivotRight = pivot.right;
    527 
    528         // move the pivot's left child to the root's right
    529         root.right = pivotLeft;
    530         if (pivotLeft != null) {
    531             pivotLeft.parent = root;
    532         }
    533 
    534         replaceInParent(root, pivot);
    535 
    536         // move the root to the pivot's left
    537         pivot.left = root;
    538         root.parent = pivot;
    539 
    540         // fix heights
    541         root.height = Math.max(left != null ? left.height : 0,
    542                 pivotLeft != null ? pivotLeft.height : 0) + 1;
    543         pivot.height = Math.max(root.height,
    544                 pivotRight != null ? pivotRight.height : 0) + 1;
    545     }
    546 
    547     /**
    548      * Rotates the subtree so that its root's left child is the new root.
    549      */
    550     private void rotateRight(Node<K, V> root) {
    551         Node<K, V> pivot = root.left;
    552         Node<K, V> right = root.right;
    553         Node<K, V> pivotLeft = pivot.left;
    554         Node<K, V> pivotRight = pivot.right;
    555 
    556         // move the pivot's right child to the root's left
    557         root.left = pivotRight;
    558         if (pivotRight != null) {
    559             pivotRight.parent = root;
    560         }
    561 
    562         replaceInParent(root, pivot);
    563 
    564         // move the root to the pivot's right
    565         pivot.right = root;
    566         root.parent = pivot;
    567 
    568         // fixup heights
    569         root.height = Math.max(right != null ? right.height : 0,
    570                 pivotRight != null ? pivotRight.height : 0) + 1;
    571         pivot.height = Math.max(root.height,
    572                 pivotLeft != null ? pivotLeft.height : 0) + 1;
    573     }
    574 
    575     /*
    576      * Navigable methods.
    577      */
    578 
    579     /**
    580      * Returns an immutable version of {@param entry}. Need this because we allow entry to be null,
    581      * in which case we return a null SimpleImmutableEntry.
    582      */
    583     private SimpleImmutableEntry<K, V> immutableCopy(Entry<K, V> entry) {
    584         return entry == null ? null : new SimpleImmutableEntry<K, V>(entry);
    585     }
    586 
    587     public Entry<K, V> firstEntry() {
    588         return immutableCopy(root == null ? null : root.first());
    589     }
    590 
    591     private Entry<K, V> internalPollFirstEntry() {
    592         if (root == null) {
    593             return null;
    594         }
    595         Node<K, V> result = root.first();
    596         removeInternal(result);
    597         return result;
    598     }
    599 
    600     public Entry<K, V> pollFirstEntry() {
    601         return immutableCopy(internalPollFirstEntry());
    602     }
    603 
    604     public K firstKey() {
    605         if (root == null) {
    606             throw new NoSuchElementException();
    607         }
    608         return root.first().getKey();
    609     }
    610 
    611     public Entry<K, V> lastEntry() {
    612         return immutableCopy(root == null ? null : root.last());
    613     }
    614 
    615     private Entry<K, V> internalPollLastEntry() {
    616         if (root == null) {
    617             return null;
    618         }
    619         Node<K, V> result = root.last();
    620         removeInternal(result);
    621         return result;
    622     }
    623 
    624     public Entry<K, V> pollLastEntry() {
    625         return immutableCopy(internalPollLastEntry());
    626     }
    627 
    628     public K lastKey() {
    629         if (root == null) {
    630             throw new NoSuchElementException();
    631         }
    632         return root.last().getKey();
    633     }
    634 
    635     public Entry<K, V> lowerEntry(K key) {
    636         return immutableCopy(find(key, LOWER));
    637     }
    638 
    639     public K lowerKey(K key) {
    640         Entry<K, V> entry = find(key, LOWER);
    641         return entry != null ? entry.getKey() : null;
    642     }
    643 
    644     public Entry<K, V> floorEntry(K key) {
    645         return immutableCopy(find(key, FLOOR));
    646     }
    647 
    648     public K floorKey(K key) {
    649         Entry<K, V> entry = find(key, FLOOR);
    650         return entry != null ? entry.getKey() : null;
    651     }
    652 
    653     public Entry<K, V> ceilingEntry(K key) {
    654         return immutableCopy(find(key, CEILING));
    655     }
    656 
    657     public K ceilingKey(K key) {
    658         Entry<K, V> entry = find(key, CEILING);
    659         return entry != null ? entry.getKey() : null;
    660     }
    661 
    662     public Entry<K, V> higherEntry(K key) {
    663         return immutableCopy(find(key, HIGHER));
    664     }
    665 
    666     public K higherKey(K key) {
    667         Entry<K, V> entry = find(key, HIGHER);
    668         return entry != null ? entry.getKey() : null;
    669     }
    670 
    671     public Comparator<? super K> comparator() {
    672         return comparator != NATURAL_ORDER ? comparator : null;
    673     }
    674 
    675     /*
    676      * View factory methods.
    677      */
    678 
    679     private EntrySet entrySet;
    680     private KeySet keySet;
    681 
    682     @Override public Set<Entry<K, V>> entrySet() {
    683         EntrySet result = entrySet;
    684         return result != null ? result : (entrySet = new EntrySet());
    685     }
    686 
    687     @Override public Set<K> keySet() {
    688         KeySet result = keySet;
    689         return result != null ? result : (keySet = new KeySet());
    690     }
    691 
    692     public NavigableSet<K> navigableKeySet() {
    693         KeySet result = keySet;
    694         return result != null ? result : (keySet = new KeySet());
    695     }
    696 
    697     public NavigableMap<K, V> subMap(K from, boolean fromInclusive, K to, boolean toInclusive) {
    698         Bound fromBound = fromInclusive ? INCLUSIVE : EXCLUSIVE;
    699         Bound toBound = toInclusive ? INCLUSIVE : EXCLUSIVE;
    700         return new BoundedMap(true, from, fromBound, to, toBound);
    701     }
    702 
    703     public SortedMap<K, V> subMap(K fromInclusive, K toExclusive) {
    704         return new BoundedMap(true, fromInclusive, INCLUSIVE, toExclusive, EXCLUSIVE);
    705     }
    706 
    707     public NavigableMap<K, V> headMap(K to, boolean inclusive) {
    708         Bound toBound = inclusive ? INCLUSIVE : EXCLUSIVE;
    709         return new BoundedMap(true, null, NO_BOUND, to, toBound);
    710     }
    711 
    712     public SortedMap<K, V> headMap(K toExclusive) {
    713         return new BoundedMap(true, null, NO_BOUND, toExclusive, EXCLUSIVE);
    714     }
    715 
    716     public NavigableMap<K, V> tailMap(K from, boolean inclusive) {
    717         Bound fromBound = inclusive ? INCLUSIVE : EXCLUSIVE;
    718         return new BoundedMap(true, from, fromBound, null, NO_BOUND);
    719     }
    720 
    721     public SortedMap<K, V> tailMap(K fromInclusive) {
    722         return new BoundedMap(true, fromInclusive, INCLUSIVE, null, NO_BOUND);
    723     }
    724 
    725     public NavigableMap<K, V> descendingMap() {
    726         return new BoundedMap(false, null, NO_BOUND, null, NO_BOUND);
    727     }
    728 
    729     public NavigableSet<K> descendingKeySet() {
    730         return new BoundedMap(false, null, NO_BOUND, null, NO_BOUND).navigableKeySet();
    731     }
    732 
    733     static class Node<K, V> implements Map.Entry<K, V> {
    734         Node<K, V> parent;
    735         Node<K, V> left;
    736         Node<K, V> right;
    737         final K key;
    738         V value;
    739         int height;
    740 
    741         Node(Node<K, V> parent, K key) {
    742             this.parent = parent;
    743             this.key = key;
    744             this.height = 1;
    745         }
    746 
    747         Node<K, V> copy(Node<K, V> parent) {
    748             Node<K, V> result = new Node<K, V>(parent, key);
    749             if (left != null) {
    750                 result.left = left.copy(result);
    751             }
    752             if (right != null) {
    753                 result.right = right.copy(result);
    754             }
    755             result.value = value;
    756             result.height = height;
    757             return result;
    758         }
    759 
    760         public K getKey() {
    761             return key;
    762         }
    763 
    764         public V getValue() {
    765             return value;
    766         }
    767 
    768         public V setValue(V value) {
    769             V oldValue = this.value;
    770             this.value = value;
    771             return oldValue;
    772         }
    773 
    774         @Override public boolean equals(Object o) {
    775             if (o instanceof Map.Entry) {
    776                 Map.Entry other = (Map.Entry) o;
    777                 return (key == null ? other.getKey() == null : key.equals(other.getKey()))
    778                         && (value == null ? other.getValue() == null : value.equals(other.getValue()));
    779             }
    780             return false;
    781         }
    782 
    783         @Override public int hashCode() {
    784             return (key == null ? 0 : key.hashCode())
    785                     ^ (value == null ? 0 : value.hashCode());
    786         }
    787 
    788         @Override public String toString() {
    789             return key + "=" + value;
    790         }
    791 
    792         /**
    793          * Returns the next node in an inorder traversal, or null if this is the
    794          * last node in the tree.
    795          */
    796         Node<K, V> next() {
    797             if (right != null) {
    798                 return right.first();
    799             }
    800 
    801             Node<K, V> node = this;
    802             Node<K, V> parent = node.parent;
    803             while (parent != null) {
    804                 if (parent.left == node) {
    805                     return parent;
    806                 }
    807                 node = parent;
    808                 parent = node.parent;
    809             }
    810             return null;
    811         }
    812 
    813         /**
    814          * Returns the previous node in an inorder traversal, or null if this is
    815          * the first node in the tree.
    816          */
    817         public Node<K, V> prev() {
    818             if (left != null) {
    819                 return left.last();
    820             }
    821 
    822             Node<K, V> node = this;
    823             Node<K, V> parent = node.parent;
    824             while (parent != null) {
    825                 if (parent.right == node) {
    826                     return parent;
    827                 }
    828                 node = parent;
    829                 parent = node.parent;
    830             }
    831             return null;
    832         }
    833 
    834         /**
    835          * Returns the first node in this subtree.
    836          */
    837         public Node<K, V> first() {
    838             Node<K, V> node = this;
    839             Node<K, V> child = node.left;
    840             while (child != null) {
    841                 node = child;
    842                 child = node.left;
    843             }
    844             return node;
    845         }
    846 
    847         /**
    848          * Returns the last node in this subtree.
    849          */
    850         public Node<K, V> last() {
    851             Node<K, V> node = this;
    852             Node<K, V> child = node.right;
    853             while (child != null) {
    854                 node = child;
    855                 child = node.right;
    856             }
    857             return node;
    858         }
    859     }
    860 
    861     /**
    862      * Walk the nodes of the tree left-to-right or right-to-left. Note that in
    863      * descending iterations, {@code next} will return the previous node.
    864      */
    865     abstract class MapIterator<T> implements Iterator<T> {
    866         protected Node<K, V> next;
    867         protected Node<K, V> last;
    868         protected int expectedModCount = modCount;
    869 
    870         MapIterator(Node<K, V> next) {
    871             this.next = next;
    872         }
    873 
    874         public boolean hasNext() {
    875             return next != null;
    876         }
    877 
    878         protected Node<K, V> stepForward() {
    879             if (next == null) {
    880                 throw new NoSuchElementException();
    881             }
    882             if (modCount != expectedModCount) {
    883                 throw new ConcurrentModificationException();
    884             }
    885             last = next;
    886             next = next.next();
    887             return last;
    888         }
    889 
    890         protected Node<K, V> stepBackward() {
    891             if (next == null) {
    892                 throw new NoSuchElementException();
    893             }
    894             if (modCount != expectedModCount) {
    895                 throw new ConcurrentModificationException();
    896             }
    897             last = next;
    898             next = next.prev();
    899             return last;
    900         }
    901 
    902         public void remove() {
    903             if (last == null) {
    904                 throw new IllegalStateException();
    905             }
    906             removeInternal(last);
    907             expectedModCount = modCount;
    908             last = null;
    909         }
    910     }
    911 
    912     /*
    913      * View implementations.
    914      */
    915 
    916     class EntrySet extends AbstractSet<Map.Entry<K, V>> {
    917         @Override public int size() {
    918             return size;
    919         }
    920 
    921         @Override public Iterator<Entry<K, V>> iterator() {
    922             return new MapIterator<Entry<K, V>>(root == null ? null : root.first()) {
    923                 public Entry<K, V> next() {
    924                     return stepForward();
    925                 }
    926             };
    927         }
    928 
    929         @Override public boolean contains(Object o) {
    930             return o instanceof Entry && findByEntry((Entry<?, ?>) o) != null;
    931         }
    932 
    933         @Override public boolean remove(Object o) {
    934             if (!(o instanceof Entry)) {
    935                 return false;
    936             }
    937 
    938             Node<K, V> node = findByEntry((Entry<?, ?>) o);
    939             if (node == null) {
    940                 return false;
    941             }
    942             removeInternal(node);
    943             return true;
    944         }
    945 
    946         @Override public void clear() {
    947             TreeMap.this.clear();
    948         }
    949     }
    950 
    951     class KeySet extends AbstractSet<K> implements NavigableSet<K> {
    952         @Override public int size() {
    953             return size;
    954         }
    955 
    956         @Override public Iterator<K> iterator() {
    957             return new MapIterator<K>(root == null ? null : root.first()) {
    958                 public K next() {
    959                     return stepForward().key;
    960                 }
    961             };
    962         }
    963 
    964         public Iterator<K> descendingIterator() {
    965             return new MapIterator<K>(root == null ? null : root.last()) {
    966                 public K next() {
    967                     return stepBackward().key;
    968                 }
    969             };
    970         }
    971 
    972         @Override public boolean contains(Object o) {
    973             return containsKey(o);
    974         }
    975 
    976         @Override public boolean remove(Object key) {
    977             return removeInternalByKey(key) != null;
    978         }
    979 
    980         @Override public void clear() {
    981             TreeMap.this.clear();
    982         }
    983 
    984         public Comparator<? super K> comparator() {
    985             return TreeMap.this.comparator();
    986         }
    987 
    988         /*
    989          * Navigable methods.
    990          */
    991 
    992         public K first() {
    993             return firstKey();
    994         }
    995 
    996         public K last() {
    997             return lastKey();
    998         }
    999 
   1000         public K lower(K key) {
   1001             return lowerKey(key);
   1002         }
   1003 
   1004         public K floor(K key) {
   1005             return floorKey(key);
   1006         }
   1007 
   1008         public K ceiling(K key) {
   1009             return ceilingKey(key);
   1010         }
   1011 
   1012         public K higher(K key) {
   1013             return higherKey(key);
   1014         }
   1015 
   1016         public K pollFirst() {
   1017             Entry<K, V> entry = internalPollFirstEntry();
   1018             return entry != null ? entry.getKey() : null;
   1019         }
   1020 
   1021         public K pollLast() {
   1022             Entry<K, V> entry = internalPollLastEntry();
   1023             return entry != null ? entry.getKey() : null;
   1024         }
   1025 
   1026         /*
   1027          * View factory methods.
   1028          */
   1029 
   1030         public NavigableSet<K> subSet(K from, boolean fromInclusive, K to, boolean toInclusive) {
   1031             return TreeMap.this.subMap(from, fromInclusive, to, toInclusive).navigableKeySet();
   1032         }
   1033 
   1034         public SortedSet<K> subSet(K fromInclusive, K toExclusive) {
   1035             return TreeMap.this.subMap(fromInclusive, true, toExclusive, false).navigableKeySet();
   1036         }
   1037 
   1038         public NavigableSet<K> headSet(K to, boolean inclusive) {
   1039             return TreeMap.this.headMap(to, inclusive).navigableKeySet();
   1040         }
   1041 
   1042         public SortedSet<K> headSet(K toExclusive) {
   1043             return TreeMap.this.headMap(toExclusive, false).navigableKeySet();
   1044         }
   1045 
   1046         public NavigableSet<K> tailSet(K from, boolean inclusive) {
   1047             return TreeMap.this.tailMap(from, inclusive).navigableKeySet();
   1048         }
   1049 
   1050         public SortedSet<K> tailSet(K fromInclusive) {
   1051             return TreeMap.this.tailMap(fromInclusive, true).navigableKeySet();
   1052         }
   1053 
   1054         public NavigableSet<K> descendingSet() {
   1055             return new BoundedMap(false, null, NO_BOUND, null, NO_BOUND).navigableKeySet();
   1056         }
   1057     }
   1058 
   1059     /*
   1060      * Bounded views implementations.
   1061      */
   1062 
   1063     enum Bound {
   1064         INCLUSIVE {
   1065             @Override public String leftCap(Object from) {
   1066                 return "[" + from;
   1067             }
   1068             @Override public String rightCap(Object to) {
   1069                 return to + "]";
   1070             }
   1071         },
   1072         EXCLUSIVE {
   1073             @Override public String leftCap(Object from) {
   1074                 return "(" + from;
   1075             }
   1076             @Override public String rightCap(Object to) {
   1077                 return to + ")";
   1078             }
   1079         },
   1080         NO_BOUND {
   1081             @Override public String leftCap(Object from) {
   1082                 return ".";
   1083             }
   1084             @Override public String rightCap(Object to) {
   1085                 return ".";
   1086             }
   1087         };
   1088 
   1089         public abstract String leftCap(Object from);
   1090         public abstract String rightCap(Object to);
   1091     }
   1092 
   1093     /**
   1094      * A map with optional limits on its range.
   1095      */
   1096     final class BoundedMap extends AbstractMap<K, V> implements NavigableMap<K, V>, Serializable {
   1097         private final transient boolean ascending;
   1098         private final transient K from;
   1099         private final transient Bound fromBound;
   1100         private final transient K to;
   1101         private final transient Bound toBound;
   1102 
   1103         BoundedMap(boolean ascending, K from, Bound fromBound, K to, Bound toBound) {
   1104             /*
   1105              * Validate the bounds. In addition to checking that from <= to, we
   1106              * verify that the comparator supports our bound objects.
   1107              */
   1108             if (fromBound != NO_BOUND && toBound != NO_BOUND) {
   1109                 if (comparator.compare(from, to) > 0) {
   1110                     throw new IllegalArgumentException(from + " > " + to);
   1111                 }
   1112             } else if (fromBound != NO_BOUND) {
   1113                 comparator.compare(from, from);
   1114             } else if (toBound != NO_BOUND) {
   1115                 comparator.compare(to, to);
   1116             }
   1117 
   1118             this.ascending = ascending;
   1119             this.from = from;
   1120             this.fromBound = fromBound;
   1121             this.to = to;
   1122             this.toBound = toBound;
   1123         }
   1124 
   1125         @Override public int size() {
   1126             return count(entrySet().iterator());
   1127         }
   1128 
   1129         @Override public boolean isEmpty() {
   1130             return endpoint(true) == null;
   1131         }
   1132 
   1133         @Override public V get(Object key) {
   1134             return isInBounds(key) ? TreeMap.this.get(key) : null;
   1135         }
   1136 
   1137         @Override public boolean containsKey(Object key) {
   1138             return isInBounds(key) && TreeMap.this.containsKey(key);
   1139         }
   1140 
   1141         @Override public V put(K key, V value) {
   1142             if (!isInBounds(key)) {
   1143                 throw outOfBounds(key, fromBound, toBound);
   1144             }
   1145             return putInternal(key, value);
   1146         }
   1147 
   1148         @Override public V remove(Object key) {
   1149             return isInBounds(key) ? TreeMap.this.remove(key) : null;
   1150         }
   1151 
   1152         /**
   1153          * Returns true if the key is in bounds.
   1154          */
   1155         @SuppressWarnings("unchecked") // this method throws ClassCastExceptions!
   1156         private boolean isInBounds(Object key) {
   1157             return isInBounds((K) key, fromBound, toBound);
   1158         }
   1159 
   1160         /**
   1161          * Returns true if the key is in bounds. Use this overload with
   1162          * NO_BOUND to skip bounds checking on either end.
   1163          */
   1164         private boolean isInBounds(K key, Bound fromBound, Bound toBound) {
   1165             if (fromBound == INCLUSIVE) {
   1166                 if (comparator.compare(key, from) < 0) {
   1167                     return false; // less than from
   1168                 }
   1169             } else if (fromBound == EXCLUSIVE) {
   1170                 if (comparator.compare(key, from) <= 0) {
   1171                     return false; // less than or equal to from
   1172                 }
   1173             }
   1174 
   1175             if (toBound == INCLUSIVE) {
   1176                 if (comparator.compare(key, to) > 0) {
   1177                     return false; // greater than 'to'
   1178                 }
   1179             } else if (toBound == EXCLUSIVE) {
   1180                 if (comparator.compare(key, to) >= 0) {
   1181                     return false; // greater than or equal to 'to'
   1182                 }
   1183             }
   1184 
   1185             return true;
   1186         }
   1187 
   1188         /**
   1189          * Returns the entry if it is in bounds, or null if it is out of bounds.
   1190          */
   1191         private Node<K, V> bound(Node<K, V> node, Bound fromBound, Bound toBound) {
   1192             return node != null && isInBounds(node.getKey(), fromBound, toBound) ? node : null;
   1193         }
   1194 
   1195         /*
   1196          * Navigable methods.
   1197          */
   1198 
   1199         public Entry<K, V> firstEntry() {
   1200             return immutableCopy(endpoint(true));
   1201         }
   1202 
   1203         public Entry<K, V> pollFirstEntry() {
   1204             Node<K, V> result = endpoint(true);
   1205             if (result != null) {
   1206                 removeInternal(result);
   1207             }
   1208             return immutableCopy(result);
   1209         }
   1210 
   1211         public K firstKey() {
   1212             Entry<K, V> entry = endpoint(true);
   1213             if (entry == null) {
   1214                 throw new NoSuchElementException();
   1215             }
   1216             return entry.getKey();
   1217         }
   1218 
   1219         public Entry<K, V> lastEntry() {
   1220             return immutableCopy(endpoint(false));
   1221         }
   1222 
   1223         public Entry<K, V> pollLastEntry() {
   1224             Node<K, V> result = endpoint(false);
   1225             if (result != null) {
   1226                 removeInternal(result);
   1227             }
   1228             return immutableCopy(result);
   1229         }
   1230 
   1231         public K lastKey() {
   1232             Entry<K, V> entry = endpoint(false);
   1233             if (entry == null) {
   1234                 throw new NoSuchElementException();
   1235             }
   1236             return entry.getKey();
   1237         }
   1238 
   1239         /**
   1240          * @param first true for the first element, false for the last.
   1241          */
   1242         private Node<K, V> endpoint(boolean first) {
   1243             Node<K, V> node;
   1244             if (ascending == first) {
   1245                 switch (fromBound) {
   1246                     case NO_BOUND:
   1247                         node = root == null ? null : root.first();
   1248                         break;
   1249                     case INCLUSIVE:
   1250                         node = find(from, CEILING);
   1251                         break;
   1252                     case EXCLUSIVE:
   1253                         node = find(from, HIGHER);
   1254                         break;
   1255                     default:
   1256                         throw new AssertionError();
   1257                 }
   1258                 return bound(node, NO_BOUND, toBound);
   1259             } else {
   1260                 switch (toBound) {
   1261                     case NO_BOUND:
   1262                         node = root == null ? null : root.last();
   1263                         break;
   1264                     case INCLUSIVE:
   1265                         node = find(to, FLOOR);
   1266                         break;
   1267                     case EXCLUSIVE:
   1268                         node = find(to, LOWER);
   1269                         break;
   1270                     default:
   1271                         throw new AssertionError();
   1272                 }
   1273                 return bound(node, fromBound, NO_BOUND);
   1274             }
   1275         }
   1276 
   1277         /**
   1278          * Performs a find on the underlying tree after constraining it to the
   1279          * bounds of this view. Examples:
   1280          *
   1281          *   bound is (A..C)
   1282          *   findBounded(B, FLOOR) stays source.find(B, FLOOR)
   1283          *
   1284          *   bound is (A..C)
   1285          *   findBounded(C, FLOOR) becomes source.find(C, LOWER)
   1286          *
   1287          *   bound is (A..C)
   1288          *   findBounded(D, LOWER) becomes source.find(C, LOWER)
   1289          *
   1290          *   bound is (A..C]
   1291          *   findBounded(D, FLOOR) becomes source.find(C, FLOOR)
   1292          *
   1293          *   bound is (A..C]
   1294          *   findBounded(D, LOWER) becomes source.find(C, FLOOR)
   1295          */
   1296         private Entry<K, V> findBounded(K key, Relation relation) {
   1297             relation = relation.forOrder(ascending);
   1298             Bound fromBoundForCheck = fromBound;
   1299             Bound toBoundForCheck = toBound;
   1300 
   1301             if (toBound != NO_BOUND && (relation == LOWER || relation == FLOOR)) {
   1302                 int comparison = comparator.compare(to, key);
   1303                 if (comparison <= 0) {
   1304                     key = to;
   1305                     if (toBound == EXCLUSIVE) {
   1306                         relation = LOWER; // 'to' is too high
   1307                     } else if (comparison < 0) {
   1308                         relation = FLOOR; // we already went lower
   1309                     }
   1310                 }
   1311                 toBoundForCheck = NO_BOUND; // we've already checked the upper bound
   1312             }
   1313 
   1314             if (fromBound != NO_BOUND && (relation == CEILING || relation == HIGHER)) {
   1315                 int comparison = comparator.compare(from, key);
   1316                 if (comparison >= 0) {
   1317                     key = from;
   1318                     if (fromBound == EXCLUSIVE) {
   1319                         relation = HIGHER; // 'from' is too low
   1320                     } else if (comparison > 0) {
   1321                         relation = CEILING; // we already went higher
   1322                     }
   1323                 }
   1324                 fromBoundForCheck = NO_BOUND; // we've already checked the lower bound
   1325             }
   1326 
   1327             return bound(find(key, relation), fromBoundForCheck, toBoundForCheck);
   1328         }
   1329 
   1330         public Entry<K, V> lowerEntry(K key) {
   1331             return immutableCopy(findBounded(key, LOWER));
   1332         }
   1333 
   1334         public K lowerKey(K key) {
   1335             Entry<K, V> entry = findBounded(key, LOWER);
   1336             return entry != null ? entry.getKey() : null;
   1337         }
   1338 
   1339         public Entry<K, V> floorEntry(K key) {
   1340             return immutableCopy(findBounded(key, FLOOR));
   1341         }
   1342 
   1343         public K floorKey(K key) {
   1344             Entry<K, V> entry = findBounded(key, FLOOR);
   1345             return entry != null ? entry.getKey() : null;
   1346         }
   1347 
   1348         public Entry<K, V> ceilingEntry(K key) {
   1349             return immutableCopy(findBounded(key, CEILING));
   1350         }
   1351 
   1352         public K ceilingKey(K key) {
   1353             Entry<K, V> entry = findBounded(key, CEILING);
   1354             return entry != null ? entry.getKey() : null;
   1355         }
   1356 
   1357         public Entry<K, V> higherEntry(K key) {
   1358             return immutableCopy(findBounded(key, HIGHER));
   1359         }
   1360 
   1361         public K higherKey(K key) {
   1362             Entry<K, V> entry = findBounded(key, HIGHER);
   1363             return entry != null ? entry.getKey() : null;
   1364         }
   1365 
   1366         public Comparator<? super K> comparator() {
   1367           if (ascending) {
   1368             return TreeMap.this.comparator();
   1369           } else {
   1370             return Collections.reverseOrder(comparator);
   1371           }
   1372         }
   1373 
   1374         /*
   1375          * View factory methods.
   1376          */
   1377 
   1378         private transient BoundedEntrySet entrySet;
   1379         private transient BoundedKeySet keySet;
   1380 
   1381         @Override public Set<Entry<K, V>> entrySet() {
   1382             BoundedEntrySet result = entrySet;
   1383             return result != null ? result : (entrySet = new BoundedEntrySet());
   1384         }
   1385 
   1386         @Override public Set<K> keySet() {
   1387             return navigableKeySet();
   1388         }
   1389 
   1390         public NavigableSet<K> navigableKeySet() {
   1391             BoundedKeySet result = keySet;
   1392             return result != null ? result : (keySet = new BoundedKeySet());
   1393         }
   1394 
   1395         public NavigableMap<K, V> descendingMap() {
   1396             return new BoundedMap(!ascending, from, fromBound, to, toBound);
   1397         }
   1398 
   1399         public NavigableSet<K> descendingKeySet() {
   1400             return new BoundedMap(!ascending, from, fromBound, to, toBound).navigableKeySet();
   1401         }
   1402 
   1403         public NavigableMap<K, V> subMap(K from, boolean fromInclusive, K to, boolean toInclusive) {
   1404             Bound fromBound = fromInclusive ? INCLUSIVE : EXCLUSIVE;
   1405             Bound toBound = toInclusive ? INCLUSIVE : EXCLUSIVE;
   1406             return subMap(from, fromBound, to, toBound);
   1407         }
   1408 
   1409         public NavigableMap<K, V> subMap(K fromInclusive, K toExclusive) {
   1410             return subMap(fromInclusive, INCLUSIVE, toExclusive, EXCLUSIVE);
   1411         }
   1412 
   1413         public NavigableMap<K, V> headMap(K to, boolean inclusive) {
   1414             Bound toBound = inclusive ? INCLUSIVE : EXCLUSIVE;
   1415             return subMap(null, NO_BOUND, to, toBound);
   1416         }
   1417 
   1418         public NavigableMap<K, V> headMap(K toExclusive) {
   1419             return subMap(null, NO_BOUND, toExclusive, EXCLUSIVE);
   1420         }
   1421 
   1422         public NavigableMap<K, V> tailMap(K from, boolean inclusive) {
   1423             Bound fromBound = inclusive ? INCLUSIVE : EXCLUSIVE;
   1424             return subMap(from, fromBound, null, NO_BOUND);
   1425         }
   1426 
   1427         public NavigableMap<K, V> tailMap(K fromInclusive) {
   1428             return subMap(fromInclusive, INCLUSIVE, null, NO_BOUND);
   1429         }
   1430 
   1431         private NavigableMap<K, V> subMap(K from, Bound fromBound, K to, Bound toBound) {
   1432             if (!ascending) {
   1433                 K fromTmp = from;
   1434                 Bound fromBoundTmp = fromBound;
   1435                 from = to;
   1436                 fromBound = toBound;
   1437                 to = fromTmp;
   1438                 toBound = fromBoundTmp;
   1439             }
   1440 
   1441             /*
   1442              * If both the current and requested bounds are exclusive, the isInBounds check must be
   1443              * inclusive. For example, to create (C..F) from (A..F), the bound 'F' is in bounds.
   1444              */
   1445 
   1446             if (fromBound == NO_BOUND) {
   1447                 from = this.from;
   1448                 fromBound = this.fromBound;
   1449             } else {
   1450                 Bound fromBoundToCheck = fromBound == this.fromBound ? INCLUSIVE : this.fromBound;
   1451                 if (!isInBounds(from, fromBoundToCheck, this.toBound)) {
   1452                     throw outOfBounds(to, fromBoundToCheck, this.toBound);
   1453                 }
   1454             }
   1455 
   1456             if (toBound == NO_BOUND) {
   1457                 to = this.to;
   1458                 toBound = this.toBound;
   1459             } else {
   1460                 Bound toBoundToCheck = toBound == this.toBound ? INCLUSIVE : this.toBound;
   1461                 if (!isInBounds(to, this.fromBound, toBoundToCheck)) {
   1462                     throw outOfBounds(to, this.fromBound, toBoundToCheck);
   1463                 }
   1464             }
   1465 
   1466             return new BoundedMap(ascending, from, fromBound, to, toBound);
   1467         }
   1468 
   1469         private IllegalArgumentException outOfBounds(Object value, Bound fromBound, Bound toBound) {
   1470             return new IllegalArgumentException(value + " not in range "
   1471                     + fromBound.leftCap(from) + ".." + toBound.rightCap(to));
   1472         }
   1473 
   1474         /*
   1475          * Bounded view implementations.
   1476          */
   1477 
   1478         abstract class BoundedIterator<T> extends MapIterator<T> {
   1479             protected BoundedIterator(Node<K, V> next) {
   1480                 super(next);
   1481             }
   1482 
   1483             @Override protected Node<K, V> stepForward() {
   1484                 Node<K, V> result = super.stepForward();
   1485                 if (next != null && !isInBounds(next.key, NO_BOUND, toBound)) {
   1486                     next = null;
   1487                 }
   1488                 return result;
   1489             }
   1490 
   1491             @Override protected Node<K, V> stepBackward() {
   1492                 Node<K, V> result = super.stepBackward();
   1493                 if (next != null && !isInBounds(next.key, fromBound, NO_BOUND)) {
   1494                     next = null;
   1495                 }
   1496                 return result;
   1497             }
   1498         }
   1499 
   1500         final class BoundedEntrySet extends AbstractSet<Entry<K, V>> {
   1501             @Override public int size() {
   1502                 return BoundedMap.this.size();
   1503             }
   1504 
   1505             @Override public boolean isEmpty() {
   1506                 return BoundedMap.this.isEmpty();
   1507             }
   1508 
   1509             @Override public Iterator<Entry<K, V>> iterator() {
   1510                 return new BoundedIterator<Entry<K, V>>(endpoint(true)) {
   1511                     public Entry<K, V> next() {
   1512                         return ascending ? stepForward() : stepBackward();
   1513                     }
   1514                 };
   1515             }
   1516 
   1517             @Override public boolean contains(Object o) {
   1518                 if (!(o instanceof Entry)) {
   1519                     return false;
   1520                 }
   1521                 Entry<?, ?> entry = (Entry<?, ?>) o;
   1522                 return isInBounds(entry.getKey()) && findByEntry(entry) != null;
   1523             }
   1524 
   1525             @Override public boolean remove(Object o) {
   1526                 if (!(o instanceof Entry)) {
   1527                     return false;
   1528                 }
   1529                 Entry<?, ?> entry = (Entry<?, ?>) o;
   1530                 return isInBounds(entry.getKey()) && TreeMap.this.entrySet().remove(entry);
   1531             }
   1532         }
   1533 
   1534         final class BoundedKeySet extends AbstractSet<K> implements NavigableSet<K> {
   1535             @Override public int size() {
   1536                 return BoundedMap.this.size();
   1537             }
   1538 
   1539             @Override public boolean isEmpty() {
   1540                 return BoundedMap.this.isEmpty();
   1541             }
   1542 
   1543             @Override public Iterator<K> iterator() {
   1544                 return new BoundedIterator<K>(endpoint(true)) {
   1545                     public K next() {
   1546                         return (ascending ? stepForward() : stepBackward()).key;
   1547                     }
   1548                 };
   1549             }
   1550 
   1551             public Iterator<K> descendingIterator() {
   1552                 return new BoundedIterator<K>(endpoint(false)) {
   1553                     public K next() {
   1554                         return (ascending ? stepBackward() : stepForward()).key;
   1555                     }
   1556                 };
   1557             }
   1558 
   1559             @Override public boolean contains(Object key) {
   1560                 return isInBounds(key) && findByObject(key) != null;
   1561             }
   1562 
   1563             @Override public boolean remove(Object key) {
   1564                 return isInBounds(key) && removeInternalByKey(key) != null;
   1565             }
   1566 
   1567             /*
   1568              * Navigable methods.
   1569              */
   1570 
   1571             public K first() {
   1572                 return firstKey();
   1573             }
   1574 
   1575             public K pollFirst() {
   1576                 Entry<K, ?> entry = pollFirstEntry();
   1577                 return entry != null ? entry.getKey() : null;
   1578             }
   1579 
   1580             public K last() {
   1581                 return lastKey();
   1582             }
   1583 
   1584             public K pollLast() {
   1585                 Entry<K, ?> entry = pollLastEntry();
   1586                 return entry != null ? entry.getKey() : null;
   1587             }
   1588 
   1589             public K lower(K key) {
   1590                 return lowerKey(key);
   1591             }
   1592 
   1593             public K floor(K key) {
   1594                 return floorKey(key);
   1595             }
   1596 
   1597             public K ceiling(K key) {
   1598                 return ceilingKey(key);
   1599             }
   1600 
   1601             public K higher(K key) {
   1602                 return higherKey(key);
   1603             }
   1604 
   1605             public Comparator<? super K> comparator() {
   1606                 return BoundedMap.this.comparator();
   1607             }
   1608 
   1609             /*
   1610              * View factory methods.
   1611              */
   1612 
   1613             public NavigableSet<K> subSet(K from, boolean fromInclusive, K to, boolean toInclusive) {
   1614                 return subMap(from, fromInclusive, to, toInclusive).navigableKeySet();
   1615             }
   1616 
   1617             public SortedSet<K> subSet(K fromInclusive, K toExclusive) {
   1618                 return subMap(fromInclusive, toExclusive).navigableKeySet();
   1619             }
   1620 
   1621             public NavigableSet<K> headSet(K to, boolean inclusive) {
   1622                 return headMap(to, inclusive).navigableKeySet();
   1623             }
   1624 
   1625             public SortedSet<K> headSet(K toExclusive) {
   1626                 return headMap(toExclusive).navigableKeySet();
   1627             }
   1628 
   1629             public NavigableSet<K> tailSet(K from, boolean inclusive) {
   1630                 return tailMap(from, inclusive).navigableKeySet();
   1631             }
   1632 
   1633             public SortedSet<K> tailSet(K fromInclusive) {
   1634                 return tailMap(fromInclusive).navigableKeySet();
   1635             }
   1636 
   1637             public NavigableSet<K> descendingSet() {
   1638                 return new BoundedMap(!ascending, from, fromBound, to, toBound).navigableKeySet();
   1639             }
   1640         }
   1641 
   1642         Object writeReplace() throws ObjectStreamException {
   1643             return ascending
   1644                     ? new AscendingSubMap<K, V>(TreeMap.this, from, fromBound, to, toBound)
   1645                     : new DescendingSubMap<K, V>(TreeMap.this, from, fromBound, to, toBound);
   1646         }
   1647     }
   1648 
   1649     /**
   1650      * Returns the number of elements in the iteration.
   1651      */
   1652     static int count(Iterator<?> iterator) {
   1653         int count = 0;
   1654         while (iterator.hasNext()) {
   1655             iterator.next();
   1656             count++;
   1657         }
   1658         return count;
   1659     }
   1660 
   1661     /*
   1662      * Serialization
   1663      */
   1664 
   1665     private static final long serialVersionUID = 919286545866124006L;
   1666 
   1667     private void writeObject(ObjectOutputStream stream) throws IOException {
   1668         stream.putFields().put("comparator", comparator != NATURAL_ORDER ? comparator : null);
   1669         stream.writeFields();
   1670         stream.writeInt(size);
   1671         for (Map.Entry<K, V> entry : entrySet()) {
   1672             stream.writeObject(entry.getKey());
   1673             stream.writeObject(entry.getValue());
   1674         }
   1675     }
   1676 
   1677     @SuppressWarnings("unchecked") // we have to trust that keys are Ks and values are Vs
   1678     private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
   1679         GetField fields = stream.readFields();
   1680         comparator = (Comparator<? super K>) fields.get("comparator", null);
   1681         if (comparator == null) {
   1682             comparator = (Comparator<? super K>) NATURAL_ORDER;
   1683         }
   1684         int size = stream.readInt();
   1685         for (int i = 0; i < size; i++) {
   1686             putInternal((K) stream.readObject(), (V) stream.readObject());
   1687         }
   1688     }
   1689 
   1690     static abstract class NavigableSubMap<K, V> extends AbstractMap<K, V> implements Serializable {
   1691         private static final long serialVersionUID = -2102997345730753016L;
   1692         TreeMap<K, V> m;
   1693         Object lo;
   1694         Object hi;
   1695         boolean fromStart;
   1696         boolean toEnd;
   1697         boolean loInclusive;
   1698         boolean hiInclusive;
   1699 
   1700         NavigableSubMap(TreeMap<K, V> delegate, K from, Bound fromBound, K to, Bound toBound) {
   1701             this.m = delegate;
   1702             this.lo = from;
   1703             this.hi = to;
   1704             this.fromStart = fromBound == NO_BOUND;
   1705             this.toEnd = toBound == NO_BOUND;
   1706             this.loInclusive = fromBound == INCLUSIVE;
   1707             this.hiInclusive = toBound == INCLUSIVE;
   1708         }
   1709 
   1710         @Override public Set<Entry<K, V>> entrySet() {
   1711             throw new UnsupportedOperationException();
   1712         }
   1713 
   1714         @SuppressWarnings("unchecked") // we have to trust that the bounds are Ks
   1715         protected Object readResolve() throws ObjectStreamException {
   1716             Bound fromBound = fromStart ? NO_BOUND : (loInclusive ? INCLUSIVE : EXCLUSIVE);
   1717             Bound toBound = toEnd ? NO_BOUND : (hiInclusive ? INCLUSIVE : EXCLUSIVE);
   1718             boolean ascending = !(this instanceof DescendingSubMap);
   1719             return m.new BoundedMap(ascending, (K) lo, fromBound, (K) hi, toBound);
   1720         }
   1721     }
   1722 
   1723     static class DescendingSubMap<K, V> extends NavigableSubMap<K, V> {
   1724         private static final long serialVersionUID = 912986545866120460L;
   1725         Comparator<K> reverseComparator;
   1726         DescendingSubMap(TreeMap<K, V> delegate, K from, Bound fromBound, K to, Bound toBound) {
   1727             super(delegate, from, fromBound, to, toBound);
   1728         }
   1729     }
   1730 
   1731     static class AscendingSubMap<K, V> extends NavigableSubMap<K, V> {
   1732         private static final long serialVersionUID = 912986545866124060L;
   1733         AscendingSubMap(TreeMap<K, V> delegate, K from, Bound fromBound, K to, Bound toBound) {
   1734             super(delegate, from, fromBound, to, toBound);
   1735         }
   1736     }
   1737 
   1738     class SubMap extends AbstractMap<K, V> implements Serializable {
   1739         private static final long serialVersionUID = -6520786458950516097L;
   1740         Object fromKey;
   1741         Object toKey;
   1742         boolean fromStart;
   1743         boolean toEnd;
   1744 
   1745         @Override public Set<Entry<K, V>> entrySet() {
   1746             throw new UnsupportedOperationException();
   1747         }
   1748 
   1749         @SuppressWarnings("unchecked") // we have to trust that the bounds are Ks
   1750         protected Object readResolve() throws ObjectStreamException {
   1751             Bound fromBound = fromStart ? NO_BOUND : INCLUSIVE;
   1752             Bound toBound = toEnd ? NO_BOUND : EXCLUSIVE;
   1753             return new BoundedMap(true, (K) fromKey, fromBound, (K) toKey, toBound);
   1754         }
   1755     }
   1756 }
   1757