Data structure - TreeMap class

Brief introduction

TreeMap collection is NavigableMap achieve red-black tree (Red-Black tree) based. The most important feature of the collection is sortable, the mappings natural ordering of its keys, or sorted according to a Comparator provided at map creation. Tree achieve two sorting methods, one way of achieving java.lang.Comparable interface and achieve its the compareTo () method. The second way is to write a class to implement a single interface java.util.Comparator, and implement compare () method, and then create an instance as constructor arguments are passaged reference TreeMap

TreeMap class
public class TreeMap<K,V> extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable

Here is a special interface NavigableMap

public interface NavigableMap<K,V> extends SortedMap<K,V>
// 找到第一个比指定的key小的值
Map.Entry<K,V> lowerEntry(K key);
// 找到第一个比指定的key小的key
K lowerKey(K key);
// 找到第一个小于或等于指定key的值
Map.Entry<K,V> floorEntry(K key);
// 找到第一个小于或等于指定key的key
K floorKey(K key);
// 找到第一个大于或等于指定key的值
Map.Entry<K,V> ceilingEntry(K key);
// 找到第一个大于或等于指定key的key
K ceilingKey(K key);
// 找到第一个大于指定key的值
Map.Entry<K,V> higherEntry(K key);
//找到第一个大于指定key的key
K higherKey(K key);
// 获取最小值
Map.Entry<K,V> firstEntry();
// 获取最大值
Map.Entry<K,V> lastEntry();
// 删除最小的元素
Map.Entry<K,V> pollFirstEntry();
// 删除最大的元素
Map.Entry<K,V> pollLastEntry();
//返回一个倒序的Map
NavigableMap<K,V> descendingMap();
// 返回一个Navigable的key的集合,NavigableSet和NavigableMap类似
NavigableSet<K> navigableKeySet();
// 对上述集合倒序
NavigableSet<K> descendingKeySet();
SortedMap Interface
public interface SortedMap<K,V> extends Map<K,V>
SortedMap method
// 排序比较器
Comparator<? super K> comparator();
// 获取其中一段
SortedMap<K,V> subMap(K fromKey, K toKey);
// 获取小于toKey的键值对
SortedMap<K,V> headMap(K toKey);
/// 获取大于fromKey的键值对
SortedMap<K,V> tailMap(K fromKey);
// 返回此映射中当前第一个键
K firstKey();
// 返回映射中当前最后一个键
K lastKey();
// 与父接口Map中的定义一样,但有顺序
Set<K> keySet();
// 与父接口Map中的定义一样,但有顺序(根据key的顺序)
Collection<V> values();
// 与父接口Map中的定义一样,但有顺序(根据key的顺序)
Set<Map.Entry<K, V>> entrySet();    

SortedMap provides a method for obtaining maximum and minimum values, but for an already sorted data sets, in addition to the maximum and minimum, we would like for any element, found less than its value and its value is greater than , you can also follow the original sorting order reverse, this time we can use the interface NavigableMap

TreeMap property
// 这是一个比较器,方便插入查找元素等操作
private final Comparator<? super K> comparator;
// 红黑树的根节点:每个节点是一个Entry
private transient Entry<K,V> root;
// 集合元素数量
private transient int size = 0;
// 集合修改的记录
private transient int modCount = 0;
TreeMap constructor
public TreeMap() {
    comparator = null;
}
public TreeMap(Comparator<? super K> comparator) {
    this.comparator = comparator;
}
public TreeMap(Map<? extends K, ? extends V> m) {
    comparator = null;
    putAll(m);
}
public TreeMap(SortedMap<K, ? extends V> m) {
    comparator = m.comparator();
    try {
        buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
    } catch (java.io.IOException cannotHappen) {
    } catch (ClassNotFoundException cannotHappen) {
    }
}

As can be seen from the properties and constructors, the TreeMap groove array is not used, and there is a root node of Entry, which is entirely tree.

Add TreeMap
public V put(K key, V value) {
    Entry<K,V> t = root;
    if (t == null) {//如果root为null 说明是添加第一个元素 直接实例化一个Entry 赋值给root
        compare(key, key); // type (and possibly null) check
        root = new Entry<>(key, value, null);
        size = 1;
        modCount++;
        return null;
    }
    int cmp;
    Entry<K,V> parent;//如果root不为null,说明已存在元素 
    // split comparator and comparable paths
    Comparator<? super K> cpr = comparator;
    if (cpr != null) { //如果比较器不为null 则使用比较器
        //找到元素的插入位置
        do {
            parent = t; //parent赋值
            cmp = cpr.compare(key, t.key);
            //当前key小于节点key 向左子树查找
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)//当前key大于节点key 向右子树查找
                t = t.right;
            else //相等的情况下 直接更新节点值
                return t.setValue(value);
        } while (t != null);
    }
    else { //如果比较器为null 则使用默认比较器
        if (key == null)//如果key为null  则抛出异常
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
        Comparable<? super K> k = (Comparable<? super K>) key;

        //找到元素的插入位置
        do {
            parent = t;
            cmp = k.compareTo(t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else
                return t.setValue(value);
        } while (t != null);
    }
    Entry<K,V> e = new Entry<>(key, value, parent);//定义一个新的节点
    //根据比较结果决定插入到左子树还是右子树
    if (cmp < 0)
        parent.left = e;
    else
        parent.right = e;
    fixAfterInsertion(e);//保持红黑树性质  插入后进行修正
    size++;//元素树自增
    modCount++;
    return null;
}

Red-black tree logic are interested to see HashMap articles

TreeMap important inner class
Entry class
static final class Entry<K,V> implements Map.Entry<K,V>

Although the internal structure is TreeMap red-black tree, but he did not use the HashMap using TreeNode object as a node

Entry properties
// 键
K key;
// 值
V value;
// 左节点
Entry<K,V> left;
// 右节点
Entry<K,V> right;
// 父节点
Entry<K,V> parent;
// 节点颜色
boolean color = BLACK;
Entry Constructor
Entry(K key, V value, Entry<K,V> parent) {
    this.key = key;
    this.value = value;
    this.parent = parent;
}
Entry method
public K getKey() {
    return key;
}
public V getValue() {
    return value;
}
public V setValue(V value) {
    V oldValue = this.value;
    this.value = value;
    return oldValue;
}
public boolean equals(Object o) {
    if (!(o instanceof Map.Entry))
        return false;
    Map.Entry<?,?> e = (Map.Entry<?,?>)o;

    return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
}
public int hashCode() {
    int keyHash = (key==null ? 0 : key.hashCode());
    int valueHash = (value==null ? 0 : value.hashCode());
    return keyHash ^ valueHash;
}

Entry own small way, maintenance tree structure mainly by TreeMap, HashMap unlike the TreeNode need to maintain their own tree

Guess you like

Origin www.cnblogs.com/yuanjiangnan/p/12613116.html