HashMap底层数据结构
Hash表 = 数组 + 线性链表 + 红黑树
数组
优点:
使用一段连续存储单元存储数据。对于指定下标的查找,时间复杂度为0(1),对于一般的插入删除操作,涉及到数组元素的移动,其平均复杂度为O(n)
缺点:
1、数组创建的时候需要指定了长度,由于数组是在内存中开辟一个连续的存储空间,长指定太大浪费空间,指定小了有不够用,再者数据组不能动态扩容;
2、我们都知道map是key-value形式,而数组只能存储单一格式的数据,所以还需要将map封装成一个对象存到数组中
3、在数组中存储key-value形式的对象时,下标是采用的hash值,在存储的过程中会出现hash碰撞,这种情况就会导致数组中的值会被覆盖掉,很显然这是我们不想看到的,所以就引入了线性链表
线性链表
对链表的新增,删除操作在查找到操作位置后,只需要处理节点间的引用即可,时间复杂度为0(1),查找操作需要遍历链表中的所有节点逐一进行对比, 复杂度为O(n)
从上图可得出数据量很大时,hash碰撞就会很多,直接导致链表很长当查找的时候效率就会很低,为了弥补这个问题在Java8里面就引入了红黑树数据结构
红黑树
红黑树: -种接近平衡二叉搜索树,在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black,通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。
红黑树定义和性质
红黑树是一种含有红黑结点并能自平衡的二叉查找树。它必须满足下面性质:
性质1:每个节点要么是黑色,要么是红色。
性质2:根节点是黑色。
性质3:每个叶子节点(NIL)是黑色。
性质4:每个红色结点的两个子结点一定都是黑色。
性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑结点。