在上一篇JDK8源码解析 -- HashMap(一)的博客中关于HashMap的重要知识点已经讲了差不多了,还有一些内容我会在今天这篇博客中说说,同时我也会把一些我不懂的问题抛出来,希望看到我这篇博客的大神帮忙解答困扰我的问题,让我明白一个所以然来。彼此互相进步,互相成长。HashMap从jdk7到jdk8版本改变大,1.新增加的节点在链表末尾进行添加  2.使用了红黑树。

1. HashMap容量大小求值方法

// 返回2的幂次
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

(1)为什么这里需要 int n = cap - 1这样呢?

首先我们要明白这个方法的作用是获取输入容量大小最近的2的幂次值。假设你传过来的参数cap是16的话,经过下面的运算得出来的值为32,而不是16。所以这里需要减去一。这样才能获此值最小的2幂次值。

(2)这里左移之和为31=1+2+4+8+16,这里为什么是31呢?

这里容量大小是int的类型,int的大小是32位,Integer的最大值是  2<sup>31</sup>-1。所以移动位数为31。还有如果 cap 不减一赋值给n的话,那么结果会超过此范围。 注意HashMap的最大容量为MAXIMUM_CAPACITY = 1 << 30;这里是30位,可能是因为如果这里是左移31的话,上面的计算值最坏的结果是1 <<< 32位,那么就超过了int的范围了,最高位是留给数字的正负符号位的。

2.快速失败机制(fail-fast)

HashMap只要结果发生了变化就会调用快速失败机制,除了iterator自己的 remove 方法,则迭代器将抛出ConcurrentModificationException。HashMap中有modCount字段记录结构改变次数,在进行迭代的时候判断此字段是否发生了变化。如果值不一样则会抛出异常。

3. 红黑树特点

(1)节点是红色或者黑色。

(2)根节点是黑色。

(3)红色节点的子节点是黑色。

(4)每个叶子节点(NIL)是黑色。  

(5)从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

注意:红色节点的子节点不能为红色,必须为黑色。黑色节点的子节点可以为红色也黑色。

抛出问题:

1.HashMap的迭代器是怎么获取值的?例如 keySet()方法如下图,我也不明白怎么实现的。HashMap中也有ValueSet()等。如果有哪位大神知道其原理,请点拨一下我。:)

JDK8源码解析 -- HashMap(二)的更多相关文章

  1. JDK8源码解析 -- HashMap(一)

    最近一直在忙于项目开发的事情,没有时间去学习一些新知识,但用忙里偷闲的时间把jdk8的hashMap源码看完了,也做了详细的笔记,我会把一些重要知识点分享给大家.大家都知道,HashMap类型也是面试 ...

  2. 老生常谈系列之Aop--Spring Aop源码解析(二)

    老生常谈系列之Aop--Spring Aop源码解析(二) 前言 上一篇文章老生常谈系列之Aop--Spring Aop源码解析(一)已经介绍完Spring Aop获取advice切面增强方法的逻辑, ...

  3. Cwinux源码解析(二)

    我在我的个人博客上发表了第二篇解析文章.欢迎各位读者批评指正. Cwinux源码解析(二)

  4. # Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析#

    Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析 Volley源码一共40多个类和接口.除去一些工具类的实现,核心代码只有20多个类.所以相对来说分析起来没有那么吃力.但是要想分析透 ...

  5. Spring事务源码解析(二)获取增强

    在上一篇文章@EnableTransactionManagement注解解析中,我们搭建了源码阅读的环境,以及解析了开启Spring事务功能的注解@EnableTransactionManagemen ...

  6. Netty 源码解析(二):Netty 的 Channel

    本文首发于微信公众号[猿灯塔],转载引用请说明出处 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty源码解析(一):开始 当前:Netty 源码解析(二): Netty 的 Channel ...

  7. AOP源码解析之二-创建AOP代理前传,获取AOP信息

    AOP源码解析之二-创建AOP代理前传,获取AOP信息. 上篇文章对AOP的基本概念说清楚了,那么接下来的AOP还剩下两个大的步骤获取定义的AOP信息,生成代理对象扔到beanFactory中. 本篇 ...

  8. 【vuejs深入三】vue源码解析之二 htmlParse解析器的实现

    写在前面 一个好的架构需要经过血与火的历练,一个好的工程师需要经过无数项目的摧残. 昨天博主分析了一下在vue中,最为基础核心的api,parse函数,它的作用是将vue的模板字符串转换成ast,从而 ...

  9. SLF4J源码解析-LoggerFactory(二)

    承接前文SLF4J源码解析-LoggerFactory(一),本文则主要针对获取ILoggerFactory对象作下简单的分析 LoggerFactory#getILoggerFactory() 源码 ...

随机推荐

  1. SpringBoot:静态资源的访问和配置(转载)

    默认静态资源访问Spring Boot的默认静态资源的路径为: spring.resources.static-locations=classpath:/META-INF/resources/,cla ...

  2. 【C语言】用C语言输出一个吃豆人

    大圆盘减去扇形和小圆盘: #include <math.h> #include <stdio.h> int main() { double x, y; ; y >= -; ...

  3. ASP.NET Core Web API 控制器与方法返回输出

    DATA ACCESS LAYER 在一些不同的示例教程中,我们可能看到 DAL 的实现在主项目中,并且每个控制器中都有实例.我们不建议这么做. 当我们编写 DAL 时,我们应该将其作为一个独立的服务 ...

  4. PHP高并发和大流量怎么解决?

    PHP高并发和大流量的解决方案 一 高并发的概念 在互联网时代,并发,高并发通常是指并发访问.也就是在某个时间点,有多少个访问同时到来. 二 高并发架构相关概念 1.QPS (每秒查询率) : 每秒钟 ...

  5. C语言随笔4:指针数组、数组指针

    数组: 1:数组名为地址,表达方法: Int A[10]; A;//数组名表示首地址 &A;//数组名加取地址符,仍然表示首地址 &A[0];//第0个元素的地址,即首地址 数组名是指 ...

  6. 将 master 节点服务器从 k8s 集群中移除并重新加入

    背景 1 台 master 加入集群后发现忘了修改主机名,而在 k8s 集群中修改节点主机名非常麻烦,不如将 master 退出集群改名并重新加入集群(前提是用的是高可用集群). 操作步骤 ssh 登 ...

  7. Multisim 如何调整编辑界面大小

    1.option -> sheet properties 2.选择workspace

  8. AS常用快捷键

    Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码(如g ...

  9. mybatis--Spring整合mybatis

    今天学习了mybatis整合Spring开发,做了一个mybatis+spring的小实例 (1)首先,创建数据库my,并在数据库my中创建表user create database my; use ...

  10. Codeforces Round #622 (Div. 2)C2

    题意 N长度为500000以内,一个数字两边的数字不能都比他高,最多高一边 求他最大sum.叙述有问题,直接看样例 3 10 6 8 因为6左右都比他高,选择10 6 6或者6 6  8,sum明显前 ...