声明,本文用得是jdk1.8html
前面已经讲了Collection的总览和剖析List集合:java
本来我是打算继续将Collection下的Set集合的,结果看了源码发现:Set集合实际上就是HashMap来构建的!git
因此,就先介绍Map集合、散列表和红黑树吧!github
看这篇文章以前最好是有点数据结构的基础:c#
固然了,若是讲得有错的地方还请你们多多包涵并不吝在评论去指正~数组
前面咱们学习的Collection叫作集合,它能够快速查找现有的元素。微信
而Map在《Core Java》中称之为-->映射..数据结构
映射的模型图是这样的:函数
那为何咱们须要这种数据存储结构呢???举个例子学习
生活中还有不少这样的例子:只要你掏出身份证(key),那就能够证实是你本身(value)
下面咱们来看看Map的源码:
简单经常使用的Map功能有这么一些:
下面用红色框框圈住的就是Map值得关注的子类:
不管是Set仍是Map,咱们会发现都会有对应的-->HashSet,HashMap
首先咱们也先得回顾一下数据和链表:
而还有另外的一些存储结构:不在乎元素的顺序,可以快速的查找元素的数据
散列表为每一个对象计算出一个整数,称为散列码。根据这些计算出来的整数(散列码)保存在对应的位置上!
在Java中,散列表用的是链表数组实现的,每一个列表称之为桶。【以前也写过桶排序就这么简单,能够回顾回顾】
一个桶上可能会遇到被占用的状况(hashCode散列码相同,就存储在同一个位置上),这种状况是没法避免的,这种现象称之为:散列冲突
若是散列表太满,是须要对散列表再散列,建立一个桶数更多的散列表,并将原有的元素插入到新表中,丢弃原来的表~
固然了, 在后面阅读源码的时候会继续说明的,如今简单了解一下便可~
扩展阅读:
上面散列表中已经提过了:若是桶数满的时候,JDK8是将链表转成红黑树的~。而且,咱们的TreeSet、TreeMap底层都是红黑树来实现的。
因此,在这里学习一波红黑树究竟是啥玩意。
以前涉及过二叉树的文章:
在未学习以前,咱们多是听过红黑树这么一个数据结构类型的,还有其余什么B/B+树等等,反正是比较复杂的数据结构了~~~
各类常见的树的用途:
来源:
https://www.zhihu.com/question/30527705/answer/52527887
首先咱们来回顾一下:利用二叉查找树的特性,咱们通常来讲能够很快地查找出对应的元素。
但是二叉查找树也有个例(最坏)的状况(线性):
上面符合二叉树的特性,可是它是线性的,彻底没树的用处~
树是要“均衡”才能将它的优势展现出来的~,好比下面这种:
所以,就有了平衡树这么一个概念~红黑树就是一种平衡树,它能够保证二叉树基本符合矮矮胖胖(均衡)的结构
讲到了平衡树就不得不说最基础的2-3树,2-3树长的是这个样子:
在二叉查找树上,咱们插入节点的过程是这样的:小于节点值往右继续与左子节点比,大于则继续与右子节点比,直到某节点左或右子节点为空,把值插入进去。这样没法避免偏向问题
而2-3树不同:它插入的时候能够保持树的平衡!
在2-3树插入的时能够简单总结为两个操做:
合并分解的操做仍是比较复杂的,要分好几种状况,代码量很大~这里我就不介绍了,由于要学起来是一大堆的,很麻烦~
因为2-3树为了保持平衡性,在维护的时候是须要大量的节点交换的!这些变换在实际代码中是很复杂的,大佬们在2-3树的理论基础上发明了红黑树(2-3-4树也是一样的道理,只是2-3树是最简单的一种状况,因此我就不说2-3-4树了)。
红黑树是一种平衡二叉树,所以它没有3-节点。那红黑树是怎么将3-节点来改进成全都是二叉树呢?
红黑树就字面上的意思,有红色的节点,有黑色的节点:
咱们能够将红色节点的左连接画平看看:
一颗典型的二叉树:
将红色节点的左连接画平以后:获得2-3平衡树:
前面已经说了,红黑树是在2-3的基础上实现的一种树,它可以用统一的方式完成全部变换。很好理解:红黑树也是平衡树的一种,在插入元素的时候它也得保持树的平衡,那红黑树是以什么的方式来保持树的平衡的呢?
红黑树用的是也是两种方式来替代2-3树不断的节点交换操做:
红黑树为了保持平衡,还有制定一些约束,遵照这些约束的才能叫作红黑树:
红黑树能够说是十分复杂的,我在学习的时候并无去认真细看当中的处理细节,只是大概的过了一遍,知道了总体~
有了前辈不少优质的资料,相信要等到想要理解其中的细节,花点力气和时间仍是能够掌握一二的。
红黑树参考资料:
这篇主要介绍了Map集合的基础知识,了解Map的经常使用子类~
简单介绍了散列表和红黑树,他俩做为Hashxxx和Treexxx的底层,了解其总体思想和相关基础在后续看源码也不至于那么懵~
后续会去看Map经常使用子类的源码,文章敬请期待~~~~
若是文章有错的地方欢迎指正,你们互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同窗,能够关注微信公众号:Java3y。为了你们方便,刚新建了一下qq群:742919422,你们也能够去交流交流。谢谢支持了!但愿能多介绍给其余有须要的朋友
参考资料: