Map接口

Map集合的特点

1.能够存储唯一的列的数据(唯一,不可重复) Set

2.能够存储可以重复的数据(可重复) List

3.值的顺序取决于键的顺序

4.键和值都是可以存储null元素的

TreeMap

本质上就是红黑树的实现

1.每个节点要么是红色,要么是黑色。

2.根节点必须是黑色

3.每个叶子节点【NIL】是黑色

4.每个红色节点的两个子节点必须是黑色

5.任意节点到每个叶子节点的路径包含相同数量的黑节点

 K key; // key
V value; // 值
Entry<K,V> left; // 左子节点
Entry<K,V> right; // 右子节点
Entry<K,V> parent; // 父节点
boolean color = BLACK; // 节点的颜色 默认是黑色

put为例

    public V put(K key, V value) {
       // 将root赋值给局部变量 null
       Entry<K,V> t = root;
       if (t == null) {
           // 初始操作
           // 检查key是否为空
           compare(key, key); // type (and possibly null) check
// 将要添加的key、 value封装为一个Entry对象 并赋值给root
           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 {
               // 将root赋值给了parent
               parent = t;
               // 和root节点比较值得大小
               cmp = cpr.compare(key, t.key);
               if (cmp < 0)
                   // 将父节点的左子节点付给了t
                   t = t.left;
               else if (cmp > 0)
                   t = t.right; // 将父节点的右节点付给了t
               else
                   // 直接和父节点的key相等,直接修改值
                   return 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;
               else
                   return t.setValue(value);
          } while (t != null);
      }
       // t 就是我们要插入节点的父节点 parent
       // 将我们要插入的key value 封装成了一个Entry对象
       Entry<K,V> e = new Entry<>(key, value, parent);
       if (cmp < 0)
           parent.left = e; // 插入的节点在parent节点的左侧
       else
           parent.right = e; // 插入的节点在parent节点的右侧
       fixAfterInsertion(e); // 实现红黑树的平衡
       size++;
       modCount++;
       return null;
  }

/** From CLR */
private void fixAfterInsertion(Entry<K,V> x) {
// 设置添加节点的颜色为 红色
x.color = RED;
// 循环的条件 添加的节点不为空 不是root节点 父节点的颜色为红色
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 = parentOf(parentOf(x));
} else { // 叔叔节点是黑色
if (x == rightOf(parentOf(x))) {
// 判断插入节点是否是 父节点的右侧节点
x = parentOf(x); // 将父节点作为插入节点
rotateLeft(x); // 左旋
}
setColor(parentOf(x), BLACK);
setColor(parentOf(parentOf(x)), RED);
rotateRight(parentOf(parentOf(x)));// 右旋
}
} else {// 父节点是祖父节点的右侧子节点
// 获取叔叔节点
Entry<K,V> y = leftOf(parentOf(parentOf(x)));
if (colorOf(y) == RED) { // 叔叔节点为红色
// recolor 变色
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;
}

TreeMap相关的更多相关文章

  1. JAVA实现的微信扫描二维码支付

    吐槽一下 支付项目采用springMvc+Dubbo架构实现,只对外提供接口. 话说,为什么微信支付比支付宝来的晚了那么一点,一句话,那一阵挺忙的,然后就没有时间整理,最近做完支付宝支付,顺便也把微信 ...

  2. Map写入的顺序 输出地顺序ZT

    偶然间 发现hashmap遍历的结果不是放入的顺序 为了项目某个功能更人性话 思考了半天还是不知道如何下手 因为有种种条件限制 后来 无意中发现 java.util.LinkedHashMap< ...

  3. 大数据系列修炼-Scala课程11

    接着昨天的list,也是学习集合的相关知识 ListBuffer.ArrayBuffer.Queue.stack相关操作 1.ListBuffer.ArrayBuffer代码实现:ListBuffer ...

  4. 死磕 java集合之ConcurrentSkipListSet源码分析——Set大汇总

    问题 (1)ConcurrentSkipListSet的底层是ConcurrentSkipListMap吗? (2)ConcurrentSkipListSet是线程安全的吗? (3)Concurren ...

  5. 【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解

    今天来介绍一下容器类中的另一个哈希表———>LinkedHashMap.这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap的全部特性,并青出于蓝而胜于蓝,有着一 ...

  6. Java 集合系列之五:Map基本操作

    1. Java Map 1. Java Map 重要观点 Java Map接口是Java Collections Framework的成员.但是它不是Collection 将键映射到值的对象.一个映射 ...

  7. 嵌入式单片机STM32应用技术(课本)

    目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...

  8. HashMap相关类:Hashtable、LinkHashMap、TreeMap

    前言 很高兴遇见你~ 在 深入剖析HashMap 文章中我从散列表的角度解析了HashMap,在 深入解析ConcurrentHashMap:感受并发编程智慧 解析了ConcurrentHashMap ...

  9. 容器--TreeMap

    一.概述 在Map的实现中,除了我们最常见的KEY值无序的HashMap之外,还有KEY有序的Map,比较常用的有两类,一类是按KEY值的大小有序的Map,这方面的代表是TreeMap,另外一种就保持 ...

随机推荐

  1. C printf 字符串格式化

    %a 浮点数.十六进制数字和p-记数法(C99) %A 浮点数.十六进制数字和p-记法(C99) %c 一个字符 %d 有符号十进制整数 %e 浮点数.e-记数法 %E 浮点数.E-记数法 %f 浮点 ...

  2. 【LeetCode】720. Longest Word in Dictionary 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力查找 排序 日期 题目地址:https://le ...

  3. C. Success Rate

    Success Rate 题目链接 题意 给你两个分数形式的数,然后有两种变化方式 上下都+1 仅下面部分+1 让你求第一个分数变化到第二个分数的最小步数. 思路 有几种特殊情况分类讨论一下. 首先我 ...

  4. 13 个 C# 10 特性

    原文链接:https://blog.okyrylchuk.dev 原文作者:Oleg Kyrylchuk 译: 等天黑 常量的内插字符串 C# 10 允许使用在常量字符串初始化中使用插值, 如下 co ...

  5. vue使用自定义指令v-dialogDrag来控制element ui中el-dialog的拖动缩放,拉伸问题

    1 在vue的utils中新建一个dialogDrag.js import Vue from 'vue' Vue.directive('dialogDrag', { bind(el, binding, ...

  6. CS5265完美替代CH7211|Type-C转HDMI2.0单转方案|CH7211替代方案

    龙迅Chrontel的CH7211是一款Type-C转HDMI2.0半导体设备,可通过USB Type-C连接器将DisplayPort信号转换为HDMI/DVI.这款创新的基于USB Type-C的 ...

  7. JavaScript交互式网页设计 • 【第3章 JavaScript浏览器对象模型】

    全部章节   >>>> 本章目录 3.1 浏览器对象模型 3.1.1 浏览器对象模型 3.2 window 对象 3.2.1 window 对象的常用属性及方法 3.2.2 使 ...

  8. C#自定义转换(implicit 或 explicit)

    C#的类型转换分为显式转换和隐式转换,显式转换需要自己声明转换类型,而隐式转换由编译器自动完成,无需我们声明,如: //long需要显式转换成int long l = 1L; int i = (int ...

  9. .net core的配置介绍(二):自定义配置(Zookeeper,数据库,Redis)

    上一篇介绍了.net core的配置原理已经系统提供的一些常用的配置,但有时我们的配置是存放在Zookeeper,DB,Redis中的,这就需要我们自己去实现集成了. 这里再介绍几个我们用的多的配置集 ...

  10. 初识python: 自定义函数

    什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率. 函数的定义方法: def test(x): '函数定义方法' x+=1 r ...