jdk8源码8---集合7----TreeMap
一、签名
public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable |
NavigableMap:可导航的Map。 Since 1.6. 它实现继承了SortedMap,成为了一个具有搜索匹配算法的Map。和TreeSet类似。
二、成员变量
private final Comparator<? super K> comparator; // 比较器。 |
private transient Entry<K,V> root; // 树的根节点 |
private transient int size = 0; // 树的entity数量 |
private transient int modCount = 0; |
static final class Entry<K,V> implements Map.Entry<K,V> { K key; V value; Entry<K,V> left; Entry<K,V> right; Entry<K,V> parent; boolean color = BLACK;
/** * Make a new cell with given key, value, and parent, and with * {@code null} child links, and BLACK color. */ Entry(K key, V value, Entry<K,V> parent) { this.key = key; this.value = value; this.parent = parent; }
/** * Returns the key. * * @return the key */ public K getKey() { return key; }
/** * Returns the value associated with the key. * * @return the value associated with the key */ public V getValue() { return value; }
/** * Replaces the value currently associated with the key with the given * value. * * @return the value associated with the key before this method was * called */ 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; }
public String toString() { return key + "=" + value; } } |
三、构造方法
public TreeMap() { //构造一个新的,空的tree map,使用key的自然顺序(没有指定比较器)。 comparator = null; } |
public TreeMap(Comparator<? super K> comparator) { // 根据指定的比较器构造一个 this.comparator = comparator; //新TreeMap } |
public TreeMap(Map<? extends K, ? extends V> m) { //将给定的map构造一个新treeMap comparator = null; // 但是按照key的自然顺序排序。 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) { } }//将给定SortMap中的数据根据SortMap中的比较器构造一个新的TreeMap。 |
四、成员方法
public V put(K key, V value) { Entry<K,V> t = root; if (t == null) { 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; // split comparator and comparable paths Comparator<? super K> cpr = comparator; if (cpr != null) { do { parent = t; cmp = cpr.compare(key, t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } else { if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") // 如果没有指定比较器。就将key强转成比较器。 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; } |
public void putAll(Map<? extends K, ? extends V> map) { int mapSize = map.size(); if (size==0 && mapSize!=0 && map instanceof SortedMap) { Comparator<?> c = ((SortedMap<?,?>)map).comparator(); if (c == comparator || (c != null && c.equals(comparator))) { ++modCount; try { buildFromSorted(mapSize, map.entrySet().iterator(), null, null); } catch (java.io.IOException cannotHappen) { } catch (ClassNotFoundException cannotHappen) { } return; } } super.putAll(map); } |
private void buildFromSorted(int size, Iterator<?> it, java.io.ObjectInputStream str, V defaultVal) throws java.io.IOException, ClassNotFoundException { this.size = size; root = buildFromSorted(0, 0, size-1, computeRedLevel(size), it, str, defaultVal); } |
// 从排序序列中构造TreeMap函数。 private final Entry<K,V> buildFromSorted(int level, int lo, int hi, int redLevel, Iterator<?> it, java.io.ObjectInputStream str, V defaultVal) throws java.io.IOException, ClassNotFoundException { //
// 树的根节点 肯定是排序序列的中间树。 // 递归处理根节点的左树,右树。 if (hi < lo) return null;
int mid = (lo + hi) >>> 1;
Entry<K,V> left = null; if (lo < mid) left = buildFromSorted(level+1, lo, mid - 1, redLevel, it, str, defaultVal);
// extract key and/or value from iterator or stream K key; V value; if (it != null) { if (defaultVal==null) { Map.Entry<?,?> entry = (Map.Entry<?,?>)it.next(); key = (K)entry.getKey(); value = (V)entry.getValue(); } else { key = (K)it.next(); value = defaultVal; } } else { // use stream key = (K) str.readObject(); value = (defaultVal != null ? defaultVal : (V) str.readObject()); }
Entry<K,V> middle = new Entry<>(key, value, null);
// color nodes in non-full bottommost level red if (level == redLevel) middle.color = RED;
if (left != null) { middle.left = left; left.parent = middle; }
if (mid < hi) { Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel, it, str, defaultVal); middle.right = right; right.parent = middle; }
return middle; } |
查找:
final Entry<K,V> getFirstEntry() { Entry<K,V> p = root; if (p != null) while (p.left != null) p = p.left; return p; } //中序遍历 获取第一个Entity |
final Entry<K,V> getLastEntry() { Entry<K,V> p = root; if (p != null) while (p.right != null) p = p.right; return p; } // 中序遍历 获取最后一个entity。 |
删除
private void deleteEntry(Entry<K,V> p) { modCount++; size--;
// If strictly internal, copy successor's element to p and then make p // point to successor. if (p.left != null && p.right != null) { Entry<K,V> s = successor(p); p.key = s.key; p.value = s.value; p = s; } // p has 2 children
// Start fixup at replacement node, if it exists. Entry<K,V> replacement = (p.left != null ? p.left : p.right);
if (replacement != null) { // Link replacement to parent replacement.parent = p.parent; if (p.parent == null) root = replacement; else if (p == p.parent.left) p.parent.left = replacement; else p.parent.right = replacement;
// Null out links so they are OK to use by fixAfterDeletion. p.left = p.right = p.parent = null;
// Fix replacement if (p.color == BLACK) fixAfterDeletion(replacement); } else if (p.parent == null) { // return if we are the only node. root = null; } else { // No children. Use self as phantom replacement and unlink. if (p.color == BLACK) fixAfterDeletion(p);
if (p.parent != null) { if (p == p.parent.left) p.parent.left = null; else if (p == p.parent.right) p.parent.right = null; p.parent = null; } } } |
static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) { if (t == null) return null; else if (t.right != null) { Entry<K,V> p = t.right; while (p.left != null) p = p.left; return p; } else { Entry<K,V> p = t.parent; Entry<K,V> ch = t; while (p != null && ch == p.right) { ch = p; p = p.parent; } return p; } } |
五、遍历方式
六、总结
1. 红黑树。
从Entiry这个内部类可以看出,TreeMap是使用红黑树这种数据结构来实现的。(Bythe way, hashMap中也用到了红黑树。)
大体上说一下红黑树的性质吧,这个我会在以后学习一下的。。。。。。。。
每个节点或是red,或是Black。
根节点是Black的。
每个叶子节点NIL是black的。
如果一个节点是Red,那么它的两个子节点都是Black。
对于每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的Black节点。
2. TreeMap在涉及到树形结构变化的时候,所实现的代码都是根据算法导论中的伪代码来的。
如果想研究一下红黑树的变化原理,请参考这篇文章:http://www.importnew.com/20413.html
最后
如果你觉得写的还不错,就关注下公众号呗,关注后,有点小礼物回赠给你。
你可以获得5000+电子书,java,springCloud,adroid,python等各种视频教程,IT类经典书籍,各种软件的安装及破解教程。
希望一块学习,一块进步!