FileDocCategorySizeDatePackage
TreeMap.javaAPI DocAndroid 1.5 API49753Wed May 06 22:41:04 BST 2009java.util

TreeMap.java

/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package java.util;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * TreeMap is an implementation of SortedMap. All optional operations (adding
 * and removing) are supported. The values can be any objects. The keys can be
 * any objects which are comparable to each other either using their natural
 * order or a specified Comparator.
 * 
 * @since Android 1.0
 */
public class TreeMap<K, V> extends AbstractMap<K, V> implements SortedMap<K, V>, Cloneable,
        Serializable {
    private static final long serialVersionUID = 919286545866124006L;

    transient int size;

    transient Entry<K, V> root;

    private Comparator<? super K> comparator;

    transient int modCount;

    transient Set<Map.Entry<K, V>> entrySet;

    /**
     * Entry is an internal class which is used to hold the entries of a
     * TreeMap.
     */
    static class Entry<K, V> extends MapEntry<K, V> {
        Entry<K, V> parent, left, right;

        boolean color;

        Entry(K key) {
            super(key);
        }

        Entry(K key, V value) {
            super(key, value);
        }

        @SuppressWarnings("unchecked")
        Entry<K, V> clone(Entry<K, V> parent) {
            Entry<K, V> clone = (Entry<K, V>) super.clone();
            clone.parent = parent;
            if (left != null) {
                clone.left = left.clone(clone);
            }
            if (right != null) {
                clone.right = right.clone(clone);
            }
            return clone;
        }
    }
    
    @SuppressWarnings("unchecked")
    private static <T> Comparable<T> toComparable(T obj) {
        return (Comparable<T>)obj;
    }

    private static class AbstractMapIterator <K,V> {
        TreeMap<K, V> backingMap;
        int expectedModCount;
        TreeMap.Entry<K, V> node;
        TreeMap.Entry<K, V> lastNode;

        AbstractMapIterator(TreeMap<K, V> map, Entry<K, V> startNode) {
            backingMap = map;
            expectedModCount = map.modCount;
            node = startNode;
        }

        public boolean hasNext() {
            return node != null;
        }

        final public void remove() {
            if (expectedModCount == backingMap.modCount) {
                if (lastNode != null) {
                    backingMap.rbDelete(lastNode);
                    lastNode = null;
                    expectedModCount++;
                } else {
                    throw new IllegalStateException();
                }
            } else {
                throw new ConcurrentModificationException();
            }
        }

        final void makeNext() {
            if (expectedModCount != backingMap.modCount) {
                throw new ConcurrentModificationException();
            } else if (node == null) {
                throw new NoSuchElementException();
            }
            lastNode = node;
            node = TreeMap.successor(node);
            }
        }

        private static class UnboundedEntryIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<Map.Entry<K, V>> {

            UnboundedEntryIterator(TreeMap<K, V> map, Entry<K, V> startNode) {
                super(map, startNode);
            }

            UnboundedEntryIterator(TreeMap<K, V> map) {
                super(map, map.root == null ? null : TreeMap.minimum(map.root));
            }

            public Map.Entry<K, V> next() {
                makeNext();
                return lastNode;
            }
        }

        static class UnboundedKeyIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<K> {
            public UnboundedKeyIterator(TreeMap<K, V> treeMap, Entry<K, V> entry) {
                super(treeMap, entry);
            }

            public UnboundedKeyIterator(TreeMap<K, V> map) {
                super(map, map.root == null ? null : TreeMap.minimum(map.root));
            }

            public K next() {
                makeNext();
                return lastNode.key;
            }
        }

        static class UnboundedValueIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<V> {
     
            public UnboundedValueIterator(TreeMap<K, V> treeMap, Entry<K, V> startNode) {
                super(treeMap, startNode);
            }
     
            public UnboundedValueIterator(TreeMap<K, V> map) {
                super(map, map.root == null ? null : TreeMap.minimum(map.root));
            }
     
            public V next() {
                makeNext();
                return lastNode.value;
            }
        }

        private static class ComparatorBoundedIterator<K, V> extends AbstractMapIterator<K, V> {
            private final  K endKey;

            private final Comparator<? super K> cmp;

        ComparatorBoundedIterator(TreeMap<K, V> map, Entry<K, V> startNode, K end) {
            super(map, startNode);
            endKey = end;
            cmp = map.comparator();
        }

        final void cleanNext() {
            if (node != null && cmp.compare(endKey, node.key) <= 0) {
                node = null;
            }
        }

        @Override
        public boolean hasNext() {
            return (node != null && endKey != null) && (cmp.compare(node.key, endKey) < 0);
        }
    }

    private static class ComparatorBoundedEntryIterator<K, V> extends
            ComparatorBoundedIterator<K, V> implements Iterator<Map.Entry<K, V>> {

        ComparatorBoundedEntryIterator(TreeMap<K, V> map, Entry<K, V> startNode, K end) {
            super(map, startNode, end);
        }

        public Map.Entry<K, V> next() {
            makeNext();
            cleanNext();
            return lastNode;
        }
    }

    private static class ComparatorBoundedKeyIterator<K, V> extends
            ComparatorBoundedIterator<K, V> implements Iterator<K> {

        ComparatorBoundedKeyIterator(TreeMap<K, V> map, Entry<K, V> startNode, K end) {
            super(map, startNode, end);
        }

        public K next() {
            makeNext();
            cleanNext();
            return lastNode.key;
        }
    }

    private static class ComparatorBoundedValueIterator<K, V> extends
            ComparatorBoundedIterator<K, V> implements Iterator<V> {

        ComparatorBoundedValueIterator(TreeMap<K, V> map, Entry<K, V> startNode, K end) {
            super(map, startNode, end);
        }

        public V next() {
            makeNext();
            cleanNext();
            return lastNode.value;
        }
    }

    private static class ComparableBoundedIterator<K, V> extends AbstractMapIterator<K, V> {
        private final Comparable<K> endKey;

        public ComparableBoundedIterator(TreeMap<K, V> treeMap, Entry<K, V> entry,
                Comparable<K> endKey) {
            super(treeMap, entry);
            this.endKey = endKey;
        }

        final void cleanNext() {
            if ((node != null) && (endKey.compareTo(node.key) <= 0)) {
                node = null;
            }
        }

        @Override
        public boolean hasNext() {
            return (node != null) && (endKey.compareTo(node.key) > 0);
        }
    }

    private static class ComparableBoundedEntryIterator<K, V> extends
            ComparableBoundedIterator<K, V> implements Iterator<Map.Entry<K, V>> {

        ComparableBoundedEntryIterator(TreeMap<K, V> map, Entry<K, V> startNode,
                Comparable<K> end) {
            super(map, startNode, end);
        }

        public Map.Entry<K, V> next() {
            makeNext();
            cleanNext();
            return lastNode;
        }

    }

    private static class ComparableBoundedKeyIterator<K, V> extends
            ComparableBoundedIterator<K, V> implements Iterator<K> {

        ComparableBoundedKeyIterator(TreeMap<K, V> map, Entry<K, V> startNode, Comparable<K> end) {
            super(map, startNode, end);
        }

        public K next() {
            makeNext();
            cleanNext();
            return lastNode.key;
        }
    }

    private static class ComparableBoundedValueIterator<K, V> extends
            ComparableBoundedIterator<K, V> implements Iterator<V> {

        ComparableBoundedValueIterator(TreeMap<K, V> map, Entry<K, V> startNode,
                Comparable<K> end) {
            super(map, startNode, end);
        }

        public V next() {
            makeNext();
            cleanNext();
            return lastNode.value;
        }
    }

        static final class SubMap<K,V> extends AbstractMap<K,V> implements SortedMap<K,V>, Serializable {
            private static final long serialVersionUID = -6520786458950516097L;

            private TreeMap<K,V> backingMap;

            boolean hasStart, hasEnd;

            K startKey, endKey;

            transient Set<Map.Entry<K,V>> entrySet = null;

            SubMap(K start, TreeMap<K,V> map) {
                backingMap = map;
                hasStart = true;
                startKey = start;
            }

            SubMap(K start, TreeMap<K,V> map, K end) {
                backingMap = map;
                hasStart = hasEnd = true;
                startKey = start;
                endKey = end;
            }
            
            SubMap(TreeMap<K,V> map, K end) {
                backingMap = map;
                hasEnd = true;
                endKey = end;
            }

            private void checkRange(K key) {
                Comparator<? super K> cmp = backingMap.comparator;
                if (cmp == null) {
                    Comparable<K> object = toComparable(key);
                    if (hasStart && object.compareTo(startKey) < 0) {
                        throw new IllegalArgumentException();
                    }
                    if (hasEnd && object.compareTo(endKey) > 0) {
                        throw new IllegalArgumentException();
                    }
                } else {
                    if (hasStart
                            && backingMap.comparator().compare(key, startKey) < 0) {
                        throw new IllegalArgumentException();
                    }
                    if (hasEnd && backingMap.comparator().compare(key, endKey) > 0) {
                        throw new IllegalArgumentException();
                    }
                }
            }

            private boolean isInRange(K key) {
                Comparator<? super K> cmp = backingMap.comparator;
                if (cmp == null) {
                    Comparable<K> object = toComparable(key);
                    if (hasStart && object.compareTo(startKey) < 0) {
                        return false;
                    }
                    if (hasEnd && object.compareTo(endKey) >= 0) {
                        return false;
                    }
                } else {
                    if (hasStart && cmp.compare(key, startKey) < 0) {
                        return false;
                    }
                    if (hasEnd && cmp.compare(key, endKey) >= 0) {
                        return false;
                    }
                }
                return true;
            }

            private boolean checkUpperBound(K key) {
                if (hasEnd) {
                    Comparator<? super K> cmp = backingMap.comparator;
                    if (cmp == null) {
                        return (toComparable(key).compareTo(endKey) < 0);
                    }
                    return (cmp.compare(key, endKey) < 0);
                }
                return true;
            }

            private boolean checkLowerBound(K key) {
                if (hasStart) {
                    Comparator<? super K> cmp = backingMap.comparator;
                    if (cmp == null) {
                        return (toComparable(key).compareTo(startKey) >= 0);
                    }
                    return (cmp.compare(key, startKey) >= 0);
                }
                return true;
            }

            public Comparator<? super K> comparator() {
                return backingMap.comparator();
            }

            @SuppressWarnings("unchecked")
            @Override
            public boolean containsKey(Object key) {
                if (isInRange((K)key)) {
                    return backingMap.containsKey(key);
                }
                return false;
            }

            @Override
            public Set<Map.Entry<K,V>> entrySet() {
                if(entrySet==null) {
                    entrySet = new SubMapEntrySet<K,V>(this);
                }
                return entrySet;
            }

            public K firstKey() {
                TreeMap.Entry<K,V> node = firstEntry();
                if (node != null ) {
                    return node.key;
                }
                throw new NoSuchElementException();
            }

            TreeMap.Entry<K,V> firstEntry() {
                if (!hasStart) {
                    TreeMap.Entry<K,V> root = backingMap.root;
                    return (root == null) ? null : minimum(backingMap.root);
                }
                TreeMap.Entry<K,V> node = backingMap.findAfter(startKey);
                if (node != null && checkUpperBound(node.key)) {
                    return node;
                }
                return null;
            }

            @SuppressWarnings("unchecked")
            @Override
            public V get(Object key) {
                if (isInRange((K)key)) {
                    return backingMap.get(key);
                }
                return null;
            }

            public SortedMap<K,V> headMap(K endKey) {
                checkRange(endKey);
                if (hasStart) {
                    return new SubMap<K,V>(startKey, backingMap, endKey);
                }
                return new SubMap<K,V>(backingMap, endKey);
            }

            @Override
            public boolean isEmpty() {
                if (hasStart) {
                    TreeMap.Entry<K,V> node = backingMap.findAfter(startKey);
                    return node == null || !checkUpperBound(node.key);
                }
                return backingMap.findBefore(endKey) == null;
            }

            @Override
            public Set<K> keySet() {
                if (keySet == null) {
                    keySet = new SubMapKeySet<K,V>(this);
                }
                return keySet;
            }

            public K lastKey() {
                if (!hasEnd) {
                    return backingMap.lastKey();
                }
                TreeMap.Entry<K,V> node = backingMap.findBefore(endKey);
                if (node != null && checkLowerBound(node.key)) {
                    return node.key;
                }
                throw new NoSuchElementException();
            }

            @Override
            public V put(K key, V value) {
                if (isInRange(key)) {
                    return backingMap.put(key, value);
                }
                throw new IllegalArgumentException();
            }

            @SuppressWarnings("unchecked")
            @Override
            public V remove(Object key) {
                if (isInRange((K)key)) {
                    return backingMap.remove(key);
                }
                return null;
            }

            public SortedMap<K,V> subMap(K startKey, K endKey) {
                checkRange(startKey);
                checkRange(endKey);
                Comparator<? super K> c = backingMap.comparator();
                if (c == null) {
                    if (toComparable(startKey).compareTo(endKey) <= 0) {
                        return new SubMap<K,V>(startKey, backingMap, endKey);
                    }
                } else {
                    if (c.compare(startKey, endKey) <= 0) {
                        return new SubMap<K,V>(startKey, backingMap, endKey);
                    }
                }
                throw new IllegalArgumentException();
            }

            public SortedMap<K,V> tailMap(K startKey) {
                checkRange(startKey);
                if (hasEnd) {
                    return new SubMap<K,V>(startKey, backingMap, endKey);
                }
                return new SubMap<K,V>(startKey, backingMap);
            }

            @Override
            public Collection<V> values() {
                if(valuesCollection==null) {
                    valuesCollection = new SubMapValuesCollection<K,V>(this);
                }
                return valuesCollection;
            }
        }

        static class SubMapEntrySet<K,V> extends AbstractSet<Map.Entry<K,V>> implements Set<Map.Entry<K,V>> {
            SubMap<K,V> subMap;

            SubMapEntrySet(SubMap<K,V> map) {
                subMap = map;
            }

            @Override
            public boolean isEmpty() {
                return subMap.isEmpty();
            }

            @Override
            public Iterator<Map.Entry<K,V>> iterator() {
                TreeMap.Entry<K,V> startNode = subMap.firstEntry();
                if (subMap.hasEnd) {
                    Comparator<? super K> cmp = subMap.comparator();
                    if (cmp == null) {
                        return new ComparableBoundedEntryIterator<K,V>(subMap.backingMap, startNode, toComparable(subMap.endKey));
                    }
                    return new ComparatorBoundedEntryIterator<K,V>(subMap.backingMap, startNode, subMap.endKey);
                }
                return new UnboundedEntryIterator<K,V>(subMap.backingMap, startNode);
            }

            @Override
            public int size() {
                int size = 0;
                Iterator<Map.Entry<K,V>> it = iterator();
                while (it.hasNext()) {
                    size++;
                    it.next();
                }
                return size;
            }

            @SuppressWarnings("unchecked")
            @Override
            public boolean contains(Object object) {
                if (object instanceof Map.Entry) {
                    Map.Entry<K,V> entry = (Map.Entry<K,V>) object;
                    K key = entry.getKey();
                    if (subMap.isInRange(key)) {
                        V v1 = subMap.get(key), v2 = entry.getValue();
                        return v1 == null ? v2 == null : v1.equals(v2);
                    }
                }
                return false;
            }

        }

        static class SubMapKeySet<K,V> extends  AbstractSet<K> implements Set<K> {
            SubMap<K,V> subMap;

            SubMapKeySet(SubMap<K,V> map) {
                subMap = map;
            }

            @Override
            public boolean contains(Object object) {
                return subMap.containsKey(object);
            }

            @Override
            public boolean isEmpty() {
                return subMap.isEmpty();
            }

            @Override
            public int size() {
                int size = 0;
                Iterator<K> it = iterator();
                while (it.hasNext()) {
                    size++;
                    it.next();
                }
                return size;
            }

            @Override
            public Iterator<K> iterator() {
                TreeMap.Entry<K,V> startNode = subMap.firstEntry();
                if (subMap.hasEnd) {
                    Comparator<? super K> cmp = subMap.comparator();
                    if (cmp == null) {
                        return new ComparableBoundedKeyIterator<K,V>(subMap.backingMap, startNode, toComparable(subMap.endKey));
                    }
                    return new ComparatorBoundedKeyIterator<K,V>(subMap.backingMap, startNode, subMap.endKey);
                }
                return new UnboundedKeyIterator<K,V>(subMap.backingMap, startNode);
            }
        }

        static class SubMapValuesCollection<K,V> extends AbstractCollection<V> {
            SubMap<K,V> subMap;

            public SubMapValuesCollection(SubMap<K,V> subMap) {
                this.subMap = subMap;
            }

            @Override
            public boolean isEmpty() {
                return subMap.isEmpty();
            }

            @Override
            public Iterator<V> iterator() {
                TreeMap.Entry<K,V> startNode = subMap.firstEntry();
                if (subMap.hasEnd) {
                    Comparator<? super K> cmp = subMap.comparator();
                    if (cmp == null) {
                        return new ComparableBoundedValueIterator<K,V>(subMap.backingMap, startNode, toComparable(subMap.endKey));
                    }
                    return new ComparatorBoundedValueIterator<K,V>(subMap.backingMap, startNode, subMap.endKey);
                }
                return new UnboundedValueIterator<K,V>(subMap.backingMap, startNode);
            }

            @Override
            public int size() {
                int cnt = 0;
                for (Iterator<V> it = iterator(); it.hasNext();) {
                    it.next();
                    cnt++;
                }
                return cnt;
            }
        }

    /**
     * Constructs a new empty {@code TreeMap} instance.
     * 
     * @since Android 1.0
     */
    public TreeMap() {
        super();
    }

    /**
     * Constructs a new empty {@code TreeMap} instance with the specified
     * comparator.
     * 
     * @param comparator
     *            the comparator to compare keys with.
     * @since Android 1.0
     */
    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }

    /**
     * Constructs a new {@code TreeMap} instance containing the mappings from
     * the specified map and using natural ordering.
     * 
     * @param map
     *            the mappings to add.
     * @throws ClassCastException
     *             if a key in the specified map does not implement the
     *             Comparable interface, or if the keys in the map cannot be
     *             compared.
     * @since Android 1.0
     */
    public TreeMap(Map<? extends K,? extends V> map) {
        this();
        putAll(map);
    }

    /**
     * Constructs a new {@code TreeMap} instance containing the mappings from
     * the specified SortedMap and using the same comparator.
     * 
     * @param map
     *            the mappings to add.
     * @since Android 1.0
     */
    public TreeMap(SortedMap<K,? extends V> map) {
        this(map.comparator());
        Iterator<? extends Map.Entry<K, ? extends V>> it = map.entrySet().iterator();
        if (it.hasNext()) {
            Map.Entry<K, ? extends V> entry = it.next();
            Entry<K, V> last = new Entry<K, V>(entry.getKey(), entry.getValue());
            root = last;
            size = 1;
            while (it.hasNext()) {
                entry = it.next();
                Entry<K, V> x = new Entry<K, V>(entry.getKey(), entry.getValue());
                x.parent = last;
                last.right = x;
                size++;
                balance(x);
                last = x;
            }
        }
    }

    void balance(Entry<K, V> x) {
        Entry<K, V> y;
        x.color = true;
        while (x != root && x.parent.color) {
            if (x.parent == x.parent.parent.left) {
                y = x.parent.parent.right;
                if (y != null && y.color) {
                    x.parent.color = false;
                    y.color = false;
                    x.parent.parent.color = true;
                    x = x.parent.parent;
                } else {
                    if (x == x.parent.right) {
                        x = x.parent;
                        leftRotate(x);
                    }
                    x.parent.color = false;
                    x.parent.parent.color = true;
                    rightRotate(x.parent.parent);
                }
            } else {
                y = x.parent.parent.left;
                if (y != null && y.color) {
                    x.parent.color = false;
                    y.color = false;
                    x.parent.parent.color = true;
                    x = x.parent.parent;
                } else {
                    if (x == x.parent.left) {
                        x = x.parent;
                        rightRotate(x);
                    }
                    x.parent.color = false;
                    x.parent.parent.color = true;
                    leftRotate(x.parent.parent);
                }
            }
        }
        root.color = false;
    }

    /**
     * Removes all mappings from this TreeMap, leaving it empty.
     * 
     * @see Map#isEmpty()
     * @see #size()
     * @since Android 1.0
     */
    @Override
    public void clear() {
        root = null;
        size = 0;
        modCount++;
    }

    /**
     * Returns a new {@code TreeMap} with the same mappings, size and comparator
     * as this instance.
     * 
     * @return a shallow copy of this instance.
     * @see java.lang.Cloneable
     * @since Android 1.0
     */
    @SuppressWarnings("unchecked")
    @Override
    public Object clone() {
        try {
            TreeMap<K, V> clone = (TreeMap<K, V>) super.clone();
            clone.entrySet = null;
            if (root != null) {
                clone.root = root.clone(null);
            }
            return clone;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    /**
     * Returns the comparator used to compare elements in this map.
     * 
     * @return the comparator or {@code null} if the natural ordering is used.
     * @since Android 1.0
     */
    public Comparator<? super K> comparator() {
        return comparator;
    }

    /**
     * Returns whether this map contains the specified key.
     * 
     * @param key
     *            the key to search for.
     * @return {@code true} if this map contains the specified key,
     *         {@code false} otherwise.
     * @since Android 1.0
     */
    @Override
    public boolean containsKey(Object key) {
        return find(key) != null;
    }

    /**
     * Returns whether this map contains the specified value.
     * 
     * @param value
     *            the value to search for.
     * @return {@code true} if this map contains the specified value,
     *         {@code false} otherwise.
     * @since Android 1.0
     */
    @Override
    public boolean containsValue(Object value) {
        if (root != null) {
            return containsValue(root, value);
        }
        return false;
    }

    private boolean containsValue(Entry<K, V> node, Object value) {
        if (value == null ? node.value == null : value.equals(node.value)) {
            return true;
        }
        if (node.left != null) {
            if (containsValue(node.left, value)) {
                return true;
            }
        }
        if (node.right != null) {
            if (containsValue(node.right, value)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns a set containing all of the mappings in this map. Each mapping is
     * an instance of {@link Map.Entry}. As the set is backed by this map,
     * changes in one will be reflected in the other. It does not support adding
     * operations.
     * 
     * @return a set of the mappings.
     * @since Android 1.0
     */
    @Override
    public Set<Map.Entry<K, V>> entrySet() {
        if (entrySet == null) {
            entrySet = new AbstractSet<Map.Entry<K, V>>() {
                 @Override
                public int size() {
                    return size;
                }

                @Override
                public void clear() {
                    TreeMap.this.clear();
                }

                @SuppressWarnings("unchecked")
                @Override
                public boolean contains(Object object) {
                    if (object instanceof Map.Entry) {
                        Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
                        Object v1 = get(entry.getKey()), v2 = entry.getValue();
                        return v1 == null ? v2 == null : v1.equals(v2);
                    }
                    return false;
                }

                @Override
                public Iterator<Map.Entry<K, V>> iterator() {
                    return new UnboundedEntryIterator<K, V>(TreeMap.this);
                }
            };
        }
        return entrySet;
    }

    @SuppressWarnings("unchecked")
    private Entry<K, V> find(Object keyObj) {
        int result;
        K key = (K)keyObj;
        Comparable<K> object = null;
        if (comparator == null) {
            object = toComparable(key);
        }
        Entry<K, V> x = root;
        while (x != null) {
            result = object != null ? object.compareTo(x.key) : comparator
                    .compare(key, x.key);
            if (result == 0) {
                return x;
            }
            x = result < 0 ? x.left : x.right;
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    Entry<K, V> findAfter(Object keyObj) {
        K key = (K)keyObj;
        int result;
        Comparable<K> object = null;
        if (comparator == null) {
            object = toComparable(key);
        }
        Entry<K, V> x = root, last = null;
        while (x != null) {
            result = object != null ? object.compareTo(x.key) : comparator
                    .compare(key, x.key);
            if (result == 0) {
                return x;
            }
            if (result < 0) {
                last = x;
                x = x.left;
            } else {
                x = x.right;
            }
        }
        return last;
    }

    Entry<K, V> findBefore(K key) {
        int result;
        Comparable<K> object = null;
        if (comparator == null) {
            object = toComparable(key);
        }
        Entry<K, V> x = root, last = null;
        while (x != null) {
            result = object != null ? object.compareTo(x.key) : comparator
                    .compare(key, x.key);
            if (result <= 0) {
                x = x.left;
            } else {
                last = x;
                x = x.right;
            }
        }
        return last;
    }

    /**
     * Returns the first key in this map.
     * 
     * @return the first key in this map.
     * @exception NoSuchElementException
     *                if this sorted map is empty.
     * @since Android 1.0
     */
    public K firstKey() {
        if (root != null) {
            return minimum(root).key;
        }
        throw new NoSuchElementException();
    }

    private void fixup(Entry<K, V> x) {
        Entry<K, V> w;
        while (x != root && !x.color) {
            if (x == x.parent.left) {
                w = x.parent.right;
                if (w == null) {
                    x = x.parent;
                    continue;
                }
                if (w.color) {
                    w.color = false;
                    x.parent.color = true;
                    leftRotate(x.parent);
                    w = x.parent.right;
                    if (w == null) {
                        x = x.parent;
                        continue;
                    }
                }
                if ((w.left == null || !w.left.color)
                        && (w.right == null || !w.right.color)) {
                    w.color = true;
                    x = x.parent;
                } else {
                    if (w.right == null || !w.right.color) {
                        w.left.color = false;
                        w.color = true;
                        rightRotate(w);
                        w = x.parent.right;
                    }
                    w.color = x.parent.color;
                    x.parent.color = false;
                    w.right.color = false;
                    leftRotate(x.parent);
                    x = root;
                }
            } else {
                w = x.parent.left;
                if (w == null) {
                    x = x.parent;
                    continue;
                }
                if (w.color) {
                    w.color = false;
                    x.parent.color = true;
                    rightRotate(x.parent);
                    w = x.parent.left;
                    if (w == null) {
                        x = x.parent;
                        continue;
                    }
                }
                if ((w.left == null || !w.left.color)
                        && (w.right == null || !w.right.color)) {
                    w.color = true;
                    x = x.parent;
                } else {
                    if (w.left == null || !w.left.color) {
                        w.right.color = false;
                        w.color = true;
                        leftRotate(w);
                        w = x.parent.left;
                    }
                    w.color = x.parent.color;
                    x.parent.color = false;
                    w.left.color = false;
                    rightRotate(x.parent);
                    x = root;
                }
            }
        }
        x.color = false;
    }

    /**
     * Returns the value of the mapping with the specified key.
     * 
     * @param key
     *            the key.
     * @return the value of the mapping with the specified key.
     * @throws ClassCastException
     *             if the key cannot be compared with the keys in this map.
     * @throws NullPointerException
     *             if the key is {@code null} and the comparator cannot handle
     *             {@code null}.
     * @since Android 1.0
     */
    @Override
    public V get(Object key) {
        Entry<K, V> node = find(key);
        if (node != null) {
            return node.value;
        }
        return null;
    }

    /**
     * Returns a sorted map over a range of this sorted map with all keys that
     * are less than the specified {@code endKey}. Changes to the returned
     * sorted map are reflected in this sorted map and vice versa.
     * <p>
     * Note: The returned map will not allow an insertion of a key outside the
     * specified range.
     * </p>
     * 
     * @param endKey
     *            the high boundary of the range specified.
     * @return a sorted map where the keys are less than {@code endKey}.
     * @throws ClassCastException
     *             if the specified key cannot be compared with the keys in this
     *             map.
     * @throws NullPointerException
     *             if the specified key is {@code null} and the comparator
     *             cannot handle {@code null} keys.
     * @throws IllegalArgumentException
     *             if this map is itself a sorted map over a range of another
     *             map and the specified key is outside of its range.
     * @since Android 1.0
     */
    public SortedMap<K, V> headMap(K endKey) {
        // Check for errors
        if (comparator == null) {
            toComparable(endKey).compareTo(endKey);
        } else {
            comparator.compare(endKey, endKey);
        }
        return new SubMap<K, V>(this, endKey);
    }

    /**
     * Returns a set of the keys contained in this map. The set is backed by
     * this map so changes to one are reflected by the other. The set does not
     * support adding.
     * 
     * @return a set of the keys.
     * @since Android 1.0
     */
    @Override
    public Set<K> keySet() {
        if (keySet == null) {
            keySet = new AbstractSet<K>() {
                @Override
                public boolean contains(Object object) {
                    return containsKey(object);
                }

                @Override
                public int size() {
                    return size;
                }

                @Override
                public void clear() {
                    TreeMap.this.clear();
                }

                @Override
                public Iterator<K> iterator() {
                    return new UnboundedKeyIterator<K,V> (TreeMap.this);
                }
            };
        }
        return keySet;
    }

    /**
     * Returns the last key in this map.
     * 
     * @return the last key in this map.
     * @throws NoSuchElementException
     *             if this map is empty.
     * @since Android 1.0
     */
    public K lastKey() {
        if (root != null) {
            return maximum(root).key;
        }
        throw new NoSuchElementException();
    }

    private void leftRotate(Entry<K, V> x) {
        Entry<K, V> y = x.right;
        x.right = y.left;
        if (y.left != null) {
            y.left.parent = x;
        }
        y.parent = x.parent;
        if (x.parent == null) {
            root = y;
        } else {
            if (x == x.parent.left) {
                x.parent.left = y;
            } else {
                x.parent.right = y;
            }
        }
        y.left = x;
        x.parent = y;
    }

    static <K, V> Entry<K, V> maximum(Entry<K, V> x) {
        while (x.right != null) {
            x = x.right;
        }
        return x;
    }

    static <K, V> Entry<K, V> minimum(Entry<K, V> x) {
        while (x.left != null) {
            x = x.left;
        }
        return x;
    }

    static <K, V> Entry<K, V> predecessor(Entry<K, V> x) {
        if (x.left != null) {
            return maximum(x.left);
        }
        Entry<K, V> y = x.parent;
        while (y != null && x == y.left) {
            x = y;
            y = y.parent;
        }
        return y;
    }

    /**
     * Maps the specified key to the specified value.
     * 
     * @param key
     *            the key.
     * @param value
     *            the value.
     * @return the value of any previous mapping with the specified key or
     *         {@code null} if there was no mapping.
     * @throws ClassCastException
     *             if the specified key cannot be compared with the keys in this
     *             map.
     * @throws NullPointerException
     *             if the specified key is {@code null} and the comparator
     *             cannot handle {@code null} keys.
     * @since Android 1.0
     */
    @Override
    public V put(K key, V value) {
        MapEntry<K, V> entry = rbInsert(key);
        V result = entry.value;
        entry.value = value;
        return result;
    }

    /**
     * Copies all the mappings in the given map to this map. These mappings will
     * replace all mappings that this map had for any of the keys currently in
     * the given map.
     * 
     * @param map
     *            the map to copy mappings from.
     * @throws ClassCastException
     *             if a key in the specified map cannot be compared with the
     *             keys in this map.
     * @throws NullPointerException
     *             if a key in the specified map is {@code null} and the
     *             comparator cannot handle {@code null} keys.
     * @since Android 1.0
     */
    @Override
    public void putAll(Map<? extends K, ? extends V> map) {
        super.putAll(map);
    }

    void rbDelete(Entry<K, V> z) {
        Entry<K, V> y = z.left == null || z.right == null ? z : successor(z);
        Entry<K, V> x = y.left != null ? y.left : y.right;
        if (x != null) {
            x.parent = y.parent;
        }
        if (y.parent == null) {
            root = x;
        } else if (y == y.parent.left) {
            y.parent.left = x;
        } else {
            y.parent.right = x;
        }
        modCount++;
        if (y != z) {
            z.key = y.key;
            z.value = y.value;
        }
        if (!y.color && root != null) {
            if (x == null) {
                fixup(y.parent);
            } else {
                fixup(x);
            }
        }
        size--;
    }

    private Entry<K, V> rbInsert(K object) {
        int result = 0;
        Entry<K, V> y = null;
        if (size != 0) {
            Comparable<K> key = null;
            if (comparator == null) {
                key = toComparable(object);
            }
            Entry<K, V> x = root;
            while (x != null) {
                y = x;
                result = key != null ? key.compareTo(x.key) : comparator
                        .compare(object, x.key);
                if (result == 0) {
                    return x;
                }
                x = result < 0 ? x.left : x.right;
            }
        }

        size++;
        modCount++;
        Entry<K, V> z = new Entry<K, V>(object);
        if (y == null) {
            return root = z;
        }
        z.parent = y;
        if (result < 0) {
            y.left = z;
        } else {
            y.right = z;
        }
        balance(z);
        return z;
    }

    /**
     * Removes the mapping with the specified key from this map.
     * 
     * @param key
     *            the key of the mapping to remove.
     * @return the value of the removed mapping or {@code null} if no mapping
     *         for the specified key was found.
     * @throws ClassCastException
     *             if the specified key cannot be compared with the keys in this
     *             map.
     * @throws NullPointerException
     *             if the specified key is {@code null} and the comparator
     *             cannot handle {@code null} keys.
     * @since Android 1.0
     */
    @Override
    public V remove(Object key) {
        if (size == 0) {
            return null;
        }
        Entry<K, V> node = find(key);
        if (node == null) {
            return null;
        }
        V result = node.value;
        rbDelete(node);
        return result;
    }

    private void rightRotate(Entry<K, V> x) {
        Entry<K, V> y = x.left;
        x.left = y.right;
        if (y.right != null) {
            y.right.parent = x;
        }
        y.parent = x.parent;
        if (x.parent == null) {
            root = y;
        } else {
            if (x == x.parent.right) {
                x.parent.right = y;
            } else {
                x.parent.left = y;
            }
        }
        y.right = x;
        x.parent = y;
    }

    /**
     * Returns the number of mappings in this map.
     * 
     * @return the number of mappings in this map.
     * @since Android 1.0
     */
    @Override
    public int size() {
        return size;
    }

    /**
     * Returns a sorted map over a range of this sorted map with all keys
     * greater than or equal to the specified {@code startKey} and less than the
     * specified {@code endKey}. Changes to the returned sorted map are
     * reflected in this sorted map and vice versa.
     * <p>
     * Note: The returned map will not allow an insertion of a key outside the
     * specified range.
     * </p>
     * 
     * @param startKey
     *            the low boundary of the range (inclusive).
     * @param endKey
     *            the high boundary of the range (exclusive),
     * @return a sorted map with the key from the specified range.
     * @throws ClassCastException
     *             if the start or end key cannot be compared with the keys in
     *             this map.
     * @throws NullPointerException
     *             if the start or end key is {@code null} and the comparator
     *             cannot handle {@code null} keys.
     * @throws IllegalArgumentException
     *             if the start key is greater than the end key, or if this map
     *             is itself a sorted map over a range of another sorted map and
     *             the specified range is outside of its range.
     * @since Android 1.0
     */
    public SortedMap<K, V> subMap(K startKey, K endKey) {
        if (comparator == null) {
            if (toComparable(startKey).compareTo(endKey) <= 0) {
                return new SubMap<K, V>(startKey, this, endKey);
            }
        } else {
            if (comparator.compare(startKey, endKey) <= 0) {
                return new SubMap<K, V>(startKey, this, endKey);
            }
        }
        throw new IllegalArgumentException();
    }

    static <K, V> Entry<K, V> successor(Entry<K, V> x) {
        if (x.right != null) {
            return minimum(x.right);
        }
        Entry<K, V> y = x.parent;
        while (y != null && x == y.right) {
            x = y;
            y = y.parent;
        }
        return y;
    }

    /**
     * Returns a sorted map over a range of this sorted map with all keys that
     * are greater than or equal to the specified {@code startKey}. Changes to
     * the returned sorted map are reflected in this sorted map and vice versa.
     * <p>
     * Note: The returned map will not allow an insertion of a key outside the
     * specified range.
     * </p>
     * 
     * @param startKey
     *            the low boundary of the range specified.
     * @return a sorted map where the keys are greater or equal to
     *         {@code startKey}.
     * @throws ClassCastException
     *             if the specified key cannot be compared with the keys in this
     *             map.
     * @throws NullPointerException
     *             if the specified key is {@code null} and the comparator
     *             cannot handle {@code null} keys.
     * @throws IllegalArgumentException
     *             if this map itself a sorted map over a range of another map
     *             and the specified key is outside of its range.
     * @since Android 1.0
     */
    public SortedMap<K, V> tailMap(K startKey) {
        // Check for errors
        if (comparator == null) {
            toComparable(startKey).compareTo(startKey);
        } else {
            comparator.compare(startKey, startKey);
        }
        return new SubMap<K, V>(startKey, this);
    }

    /**
     * Returns a collection of the values contained in this map. The collection
     * is backed by this map so changes to one are reflected by the other. The
     * collection supports remove, removeAll, retainAll and clear operations,
     * and it does not support add or addAll operations.
     * <p>
     * This method returns a collection which is the subclass of
     * AbstractCollection. The iterator method of this subclass returns a
     * "wrapper object" over the iterator of map's entrySet(). The {@code size}
     * method wraps the map's size method and the {@code contains} method wraps
     * the map's containsValue method.
     * </p>
     * <p>
     * The collection is created when this method is called for the first time
     * and returned in response to all subsequent calls. This method may return
     * different collections when multiple concurrent calls occur, since no
     * synchronization is performed.
     * </p>
     * 
     * @return a collection of the values contained in this map.
     * @since Android 1.0
     */
    @Override
    public Collection<V> values() {
        if (valuesCollection == null) {
            valuesCollection = new AbstractCollection<V>() {
                @Override
                public boolean contains(Object object) {
                    return containsValue(object);
                }

                @Override
                public int size() {
                    return size;
                }

                @Override
                public void clear() {
                    TreeMap.this.clear();
                }

                @Override
                public Iterator<V> iterator() {
                    return new UnboundedValueIterator<K,V> (TreeMap.this);
                }
            };
        }
        return valuesCollection;
    }

    private void writeObject(ObjectOutputStream stream) throws IOException {
        stream.defaultWriteObject();
        stream.writeInt(size);
        if (size > 0) {
            Entry<K, V> node = minimum(root);
            while (node != null) {
                stream.writeObject(node.key);
                stream.writeObject(node.value);
                node = successor(node);
            }
        }
    }

    @SuppressWarnings("unchecked")
    private void readObject(ObjectInputStream stream) throws IOException,
            ClassNotFoundException {
        stream.defaultReadObject();
        size = stream.readInt();
        Entry<K, V> last = null;
        for (int i = size; --i >= 0;) {
            Entry<K, V> node = new Entry<K, V>((K)stream.readObject());
            node.value = (V)stream.readObject();
            if (last == null) {
                root = node;
            } else {
                node.parent = last;
                last.right = node;
                balance(node);
            }
            last = node;
        }
    }
}