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++内存分布之虚函数(多继承)

    系列 c++内存分布之虚函数(单一继承) c++内存分布之虚函数(多继承) [本文] 结论 1.虚函数表指针 和 虚函数表 1.1 影响虚函数表指针个数的因素只和派生类的父类个数有关.多一个父类,派生 ...

  2. chrome/microsoft/brave等浏览器离线下载crx并安装(解决download interrupted)

    重要网站 离线下载crx 问题描述 使用chrome/microsoft edge/ brave 下载chrome webstroe插件时,提示: download interrupted. 解决方案 ...

  3. D. Substring

    D. Substring 题意: 给你一个有向图,然后给你一串字符串第i个点的值为第i个字符,然后给你m条有向边,从中找一条路径然后这条路径中点的值相同的个数的最大值,如果图有环输出-1. 思路: 拓 ...

  4. codeforce-601A. The Two Routes(最短路)

    题意: 给你N个点表示N个站,有汽车和火车,汽车只能走公路,火车只能走铁路. 然后给你M条双向路,代表这两个点之间有铁路连接. 然后告诉你如果两个点之间没有铁路,那么就是公路连接. 问你汽车和火车都到 ...

  5. 1114. Boxes

    1114. Boxes Time limit: 0.6 secondMemory limit: 64 MB N boxes are lined up in a sequence (1 ≤ N ≤ 20 ...

  6. MCU变量加载过程

    前言 在开发mcu代码的时候经常会有些疑惑,变量是怎么在编译之后进入单片机的ram区的呢,特别是在使用keil开发的时候.后来在接触gcc编译器和自研的mcu后,终于明白了这个问题.实际上变量编译后被 ...

  7. Java初学者作业——定义英雄类(Hero),英雄类中的属性包括:姓名、攻击力、防御力、生命值和魔法值;方法包括:攻击、介绍。

    返回本章节 返回作业目录 需求说明: 定义英雄类(Hero),英雄类中的属性包括:姓名.攻击力.防御力.生命值和魔法值:方法包括:攻击.介绍. 实现思路: 分析类的属性及其变量类型. 分析类的方法及其 ...

  8. SpringBoot 原理分析、监控、项目部署

    目录 SpringBoot 监控 概述 使用 SpringBoot Admin 概述 使用 SpringBoot 项目部署 SpringBoot 监控 概述 SpringBoot 自带监控功能 Act ...

  9. python 自动化测试框架unittest与pytest的区别

    前言: 有使用过unittest单元测试框架,再使用pytest单元测试框架,就可以明显感觉到pytest比unittest真的简洁.方便很多. unittest与pytest的区别: 主要从用例编写 ...

  10. Appium服务器初始化参数(Capability)

    原文:https://blog.csdn.net/lilongsy/article/details/83010101 appium官方说明:https://appium.io/docs/cn/writ ...