一、属性

1.1 Entry

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;}}

二、方法

2.1 put

将特定的键值对储存进入map中,如果这个map已经包含了Key,那么更新Value的值,同时会返回这个旧值。如果不包含这个Key,那么返回null,注意返回null还有可能是Key对应的值为null。

/*** @throws ClassCastException if the specified key cannot be compared*         with the keys currently in the map* @throws NullPointerException if the specified key is null*         and this map uses natural ordering, or its comparator*         does not permit null keys*/public V put(K key, V value) {Entry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}int cmp;Entry<K,V> parent;// split comparator and comparable pathsComparator<? 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;elsereturn t.setValue(value);} while (t != null);}else {if (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;elsereturn t.setValue(value);} while (t != null);}Entry<K,V> e = new Entry<>(key, value, parent);if (cmp < 0)parent.left = e;elseparent.right = e;fixAfterInsertion(e);size++;modCount++;return null;}

2.2 get

返回和特定Key值对应的Value,如果不存在,返回null(注意返回null还有可能是Key对应的Value等于null,可以用containsKey来进行区分)。

/*** @throws ClassCastException if the specified key cannot be compared*         with the keys currently in the map* @throws NullPointerException if the specified key is null*         and this map uses natural ordering, or its comparator*         does not permit null keys*/public V get(Object key) {Entry<K,V> p = getEntry(key);return (p==null ? null : p.value);}

2.2.1 getEntry

返回和Key相对应的map的实体,如果不存在,返回null。

/*** @throws ClassCastException if the specified key cannot be compared*         with the keys currently in the map* @throws NullPointerException if the specified key is null*         and this map uses natural ordering, or its comparator*         does not permit null keys*/final Entry<K,V> getEntry(Object key) {// Offload comparator-based version for sake of performanceif (comparator != null)return getEntryUsingComparator(key);if (key == null)throw new NullPointerException();@SuppressWarnings("unchecked")Comparable<? super K> k = (Comparable<? super K>) key;Entry<K,V> p = root;while (p != null) {int cmp = k.compareTo(p.key);if (cmp < 0)p = p.left;else if (cmp > 0)p = p.right;elsereturn p;}return null;}

2.2.1.1 getEntryUsingComparator

使用Comparator进行判断的版本

/*** Version of getEntry using comparator. Split off from getEntry* for performance. (This is not worth doing for most methods,* that are less dependent on comparator performance, but is* worthwhile here.)*/final Entry<K,V> getEntryUsingComparator(Object key) {@SuppressWarnings("unchecked")K k = (K) key;Comparator<? super K> cpr = comparator;if (cpr != null) {Entry<K,V> p = root;while (p != null) {int cmp = cpr.compare(k, p.key);if (cmp < 0)p = p.left;else if (cmp > 0)p = p.right;elsereturn p;}}return null;}

2.3 containsValue

如果有至少一个的Key对应这个Value值,则返回true,这个操作是线性的时间复杂度(意味着要遍历整个树)

    public boolean containsValue(Object value) {for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))if (valEquals(value, e.value))return true;return false;}

2.4 getFirstEntry

返回二叉搜索树的最小节点

final Entry<K,V> getFirstEntry() {Entry<K,V> p = root;if (p != null)while (p.left != null)p = p.left;return p;}

2.5 getLastEntry

返回二叉搜索树的最大节点

final Entry<K,V> getLastEntry() {Entry<K,V> p = root;if (p != null)while (p.right != null)p = p.right;return p;}

2.6 remove

如果存在和Key对应的键值对,那么在这个TreeMap中删除这个键值对。返回之前和这个Key对应的Value,如果不存在,返回null(注意返回null也可能是Key对应的Value值为null)

/** @throws ClassCastException if the specified key cannot be compared*         with the keys currently in the map* @throws NullPointerException if the specified key is null*         and this map uses natural ordering, or its comparator*         does not permit null keys*/public V remove(Object key) {Entry<K,V> p = getEntry(key);if (p == null)return null;V oldValue = p.value;deleteEntry(p);return oldValue;}

2.6.1 deleteEntry

    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) {//这里s是p右孩子中最小的节点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);//p只有一个孩子的情况if (replacement != null) {// Link replacement to parentreplacement.parent = p.parent;if (p.parent == null)root = replacement;else if (p == p.parent.left)p.parent.left  = replacement;elsep.parent.right = replacement;//这里做的操作是先删除p,然后调整树// Null out links so they are OK to use by fixAfterDeletion.p.left = p.right = p.parent = null;// Fix replacementif (p.color == BLACK)fixAfterDeletion(replacement);} else if (p.parent == null) { // return if we are the only node.root = null;} else { //p是叶子节点的情况//先调整,再删除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;}}}

2.7 successor

寻找传入节点的后继节点

/*** Returns the successor of the specified Entry, or null if no such.*/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;}}

2.8 predecessor

寻找当前节点的前驱节点

 /*** Returns the predecessor of the specified Entry, or null if no such.*/static <K,V> Entry<K,V> predecessor(Entry<K,V> t) {if (t == null)return null;else if (t.left != null) {Entry<K,V> p = t.left;while (p.right != null)p = p.right;return p;} else {Entry<K,V> p = t.parent;Entry<K,V> ch = t;while (p != null && ch == p.left) {ch = p;p = p.parent;}return p;}}

2.9 fixAfterInsertion

/** From CLR */private void fixAfterInsertion(Entry<K,V> x) {x.color = RED;while (x != null && x != root && x.parent.color == RED) {//父节点是爷爷结点的左结点if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {//取得父亲结点的兄弟结点(叔叔结点)Entry<K,V> y = rightOf(parentOf(parentOf(x)));//叔叔结点为红色,此时子节点可左可右if (colorOf(y) == RED) {//将父亲结点和叔叔结点染黑setColor(parentOf(x), BLACK);setColor(y, BLACK);//将爷爷结点染红setColor(parentOf(parentOf(x)), RED);//X回溯至爷爷结点x = parentOf(parentOf(x));} else {//叔叔结点为黑色if (x == rightOf(parentOf(x))) {//X是P的右孩子//x指向px = parentOf(x);//左旋protateLeft(x);}//将P染黑,G染红setColor(parentOf(x), BLACK);setColor(parentOf(parentOf(x)), RED);//右旋GrotateRight(parentOf(parentOf(x)));}} else {Entry<K,V> y = leftOf(parentOf(parentOf(x)));if (colorOf(y) == RED) {setColor(parentOf(x), BLACK);setColor(y, BLACK);setColor(parentOf(parentOf(x)), RED);x = parentOf(parentOf(x));} else {if (x == leftOf(parentOf(x))) {x = parentOf(x);rotateRight(x);}setColor(parentOf(x), BLACK);setColor(parentOf(parentOf(x)), RED);rotateLeft(parentOf(parentOf(x)));}}}root.color = BLACK;}

2.10 fixAfterDeletion

/** From CLR */private void fixAfterDeletion(Entry<K,V> x) {//节点x的颜色为黑while (x != root && colorOf(x) == BLACK) {//当x是左节点时if (x == leftOf(parentOf(x))) {Entry<K,V> sib = rightOf(parentOf(x));//第一种情况,兄弟节点S为红色if (colorOf(sib) == RED) {//将S染黑setColor(sib, BLACK);//将P染红,左旋PsetColor(parentOf(x), RED);rotateLeft(parentOf(x));sib = rightOf(parentOf(x));}//兄弟节点为黑色的情况if (colorOf(leftOf(sib))  == BLACK &&colorOf(rightOf(sib)) == BLACK) {//左侄子和右侄子均为黑色//将S染红setColor(sib, RED);//X回溯至Px = parentOf(x);} else {if (colorOf(rightOf(sib)) == BLACK) {//S为黑色,LN为红色,RN为黑色//将LN染黑setColor(leftOf(sib), BLACK);//将S染红setColor(sib, RED);//右旋SrotateRight(sib);//S指向LNsib = rightOf(parentOf(x));}//第四种情况//S为黑色,P可红可黑,RN为红色,LN可红可黑//将S的颜色设置为与P相同setColor(sib, colorOf(parentOf(x)));//P染黑setColor(parentOf(x), BLACK);//RN染黑setColor(rightOf(sib), BLACK);//左旋ProtateLeft(parentOf(x));//X回溯至根节点x = root;}} else { // symmetricEntry<K,V> sib = leftOf(parentOf(x));if (colorOf(sib) == RED) {setColor(sib, BLACK);setColor(parentOf(x), RED);rotateRight(parentOf(x));sib = leftOf(parentOf(x));}if (colorOf(rightOf(sib)) == BLACK &&colorOf(leftOf(sib)) == BLACK) {setColor(sib, RED);x = parentOf(x);} else {if (colorOf(leftOf(sib)) == BLACK) {setColor(rightOf(sib), BLACK);setColor(sib, RED);rotateLeft(sib);sib = leftOf(parentOf(x));}setColor(sib, colorOf(parentOf(x)));setColor(parentOf(x), BLACK);setColor(leftOf(sib), BLACK);rotateRight(parentOf(x));x = root;}}}//回溯过程,不管X是根节点还是红色节点,均调整为黑色setColor(x, BLACK);}

jdk TreeMap源码解析相关推荐

  1. TreeMap源码解析

    1.TreeMap介绍 TreeMap是一个通过红黑树实现有序的key-value集合. TreeMap继承AbstractMap,也即实现了Map,它是一个Map集合 TreeMap实现了Navig ...

  2. Java集合之TreeMap源码解析上篇

    上期回顾 上期我从树型结构谈到了红黑树的概念以及自平衡的各种变化(指路上期←戳),本期我将会对TreeMap结合红黑树理论进行解读. 首先,我们先来回忆一下红黑树的5条基本规则. 1.结点是红色或者黑 ...

  3. Java TreeMap 源码解析

    继上篇文章介绍完了HashMap,这篇文章开始介绍Map系列另一个比较重要的类TreeMap. 大家也许能感觉到,网络上介绍HashMap的文章比较多,但是介绍TreeMap反而不那么多,这里面是有原 ...

  4. JDK 8源码解析——String中的intern()方法

    String是最常用的类之一,也许就是太常见了,因此导致经常忽略它存在,即使在观察堆得时候发现String类以及char[]所占的内存比较多的时候,也潜意识的跳过了它们.其实,String类以及cha ...

  5. TreeMap源码解析。

    /*** 基于红黑树(Red-Black tree)的 NavigableMap 实现.该映射根据其键的自然顺序进行排序,* 或者根据创建映射时提供的Comparator 进行排序,具体取决于使用的构 ...

  6. Java集合系列---TreeMap源码解析(巨好懂!!!)

    TreeMap底层是基于红黑树实现,能实现根据key值对节点进行排序,排序可分为自然排序和定制排序. 自然排序:TreeMap的所有key必须实现Comparable接口, 定制排序:创建TreeMa ...

  7. 2.8 SortedMap接口与TreeMap源码解析

    2.8 SortedMap接口 SortedMap继承自Map接口,是一种有序的Map. public interface SortedMap<K,V> extends Map<K, ...

  8. TreeSet源码解析

    TreeSet概述 所有实现的接口: Serializable, Cloneable, Iterable<E>, Collection<E>, NavigableSet< ...

  9. 死磕 java集合之TreeMap源码分析(一)——红黑树全解析

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 TreeMap使用红黑树存储元素,可以保证元素按key值的大小进行遍历. 继承体系 Tr ...

  10. JDK源码解析 迭代器模式在JAVA的很多集合类中被广泛应用,接下来看看JAVA源码中是如何使用迭代器模式的。

    JDK源码解析 迭代器模式在JAVA的很多集合类中被广泛应用,接下来看看JAVA源码中是如何使用迭代器模式的. 看完这段代码是不是很熟悉,与我们上面代码基本类似.单列集合都使用到了迭代器,我们以Arr ...

最新文章

  1. ncurse界面编程多线程示例
  2. Netty自定义协议
  3. 大型主机CICS中间件基础
  4. React开发(136):ant design学习指南之form中动态form新增删除
  5. C语言条件判断 if / else - C语言零基础入门教程
  6. 切割图形_泉州泡沫景观字切割机厂家
  7. Gridview导出到EXCEL
  8. Visual Studio 2019 RC入门——第2部分
  9. sudo gem install cocoapods
  10. selenium——鼠标事件
  11. selenium之时间日期控件的处理
  12. .NET反编译工具:de4dot
  13. 图片选择器ImagePicker
  14. android中的后退功能,在Android中单击按钮时触发后退按钮功能
  15. H5特效demo网站
  16. AirtestIDE1.2.13的安卓手机设置自动初始化功能
  17. juniper SRX55 简单配置
  18. 树莓派4B 8G安装日志(1)——基础环境安装
  19. 2021-05-01Java面试知识点
  20. QM的计算机专业,PCM5-QM170

热门文章

  1. esayexcel导出动态表头数据
  2. 每天一点正则表达式积累之(?=X)和(?!X)测试(七)
  3. vc access mysql_VC中访问Access数据库的方法
  4. 都在这儿了!Flink Forward Asia 最佳参会指南
  5. 蚂蚁员工人均都能买1套杭州的房子了?!好后悔,当初错失了蚂蚁...
  6. 谷歌宣布Kotlin成安卓开发一级语言,我们如何来学习它
  7. FFmpeg总结(四)AV系列结构体之AVBuffer、AVBufferRef、AVBufferPool
  8. 性能测试--jmeter如何发送post请求【4】
  9. 单按钮启停电路实物图_什么是电路的主回路?什么是控制回路?它们之间有什么区别?...
  10. js 正则匹配邮箱_比较正宗的验证邮箱的正则表达式js代码详解