什么是红黑树?
红黑树是一种特殊的二叉查找树,红黑树的每个结点上都有存储位表示结点的颜色,可以是红(Red)或黑(Black)。
红黑树的每个结点是红色或者黑色。但是不管怎么样他的根结点是黑色。每个为空的叶子结点也是黑色
如果一个结点是红色的,则它的子结点必须是黑色的。
每个结点到叶子结点所经过的黑色结点的个数一样的。(确保没有一条路径会比其他路径长出俩倍,所以红黑树是相对接近平衡的二叉树的)
红黑树的基本操作是添加、删除。在对红黑树进行添加或删除之后,都会用到旋转方法。保证这颗树依然是红黑树。
HashMap的扩容操作是怎么实现的?
在jdk1.8中,resize方法是在hashmap中的键值对大于阀值时或者初始化时,就调用resize方法进
行扩容;
每次扩展的时候,都是扩展2倍;
扩展后Node对象的位置要么在原位置,要么移动到原偏移量两倍的位置。
在putVal()中,我们看到在这个函数里面使用到了2次resize()方法,resize()方法表示的在进行第一次初始化时会对其进行扩容,或者当该数组的实际大小大于其临界值值(第一次为12),这个时候在扩容的同时也会伴随的桶上面的元素进行重新分发,这也是JDK1.8版本的一个优化的地方,在1.7中,扩容之后需要重新去计算其Hash值,根据Hash值对其进行分发,但在1.8版本中,则是根据在同一个桶的位置中进行判断(e.hash & oldCap)是否为0,重新进行hash分配后,该元素的位置要么停留在原始位置,要么移动到原始位置+增加的数组大小这个位置上
HashMap 的长度为什么是2的幂次方
为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀,每个链表/红黑树长度大致相同。这个实现就是把数据存到哪个链表/红黑树中的算法。我们首先可能会想到采用%取余的操作来实现。但是取余(%)操作中如果除数是2的幂次则等价于与其除数减一的与(&)操作(也就是说 hash%length==hash&(length-1)的前提是 length 是2的 n 次方;)。并且 采用二进制位操作 &,相对于%能够提高运算效率,这就解释了 HashMap 的长度为什么是2的幂次方。
ConcurrentHashMap的实现原理
JDK1.7 的 ConcurrentHashMap 底层采⽤分段(Segment)的数组+链表实现,⼀个 ConcurrentHashMap ⾥包含⼀个 Segment 数组,每个Segment中都包含了一个HashEntry数组,HashEntry ⽤于存储键值对数据,HashEntry之间组成了链表结构。每⼀段数据配⼀把ReentranLock锁,当⼀个线程占⽤锁访问其中⼀个段数据时,其他段的数据也能被其他线程访问。
元素查找:二次hash,第一次定位segment字段,第二次hash定位到元素所在的链表的头部
给同学们带来全新的Java300集课程啦!java零基础小白自学Java必备优质教程_手把手图解学习Java,让学习成为一种享受_哔哩哔哩_bilibili