JDK8源码解析 -- HashMap(二)
在上一篇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(二)的更多相关文章
- JDK8源码解析 -- HashMap(一)
最近一直在忙于项目开发的事情,没有时间去学习一些新知识,但用忙里偷闲的时间把jdk8的hashMap源码看完了,也做了详细的笔记,我会把一些重要知识点分享给大家.大家都知道,HashMap类型也是面试 ...
- 老生常谈系列之Aop--Spring Aop源码解析(二)
老生常谈系列之Aop--Spring Aop源码解析(二) 前言 上一篇文章老生常谈系列之Aop--Spring Aop源码解析(一)已经介绍完Spring Aop获取advice切面增强方法的逻辑, ...
- Cwinux源码解析(二)
我在我的个人博客上发表了第二篇解析文章.欢迎各位读者批评指正. Cwinux源码解析(二)
- # Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析#
Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析 Volley源码一共40多个类和接口.除去一些工具类的实现,核心代码只有20多个类.所以相对来说分析起来没有那么吃力.但是要想分析透 ...
- Spring事务源码解析(二)获取增强
在上一篇文章@EnableTransactionManagement注解解析中,我们搭建了源码阅读的环境,以及解析了开启Spring事务功能的注解@EnableTransactionManagemen ...
- Netty 源码解析(二):Netty 的 Channel
本文首发于微信公众号[猿灯塔],转载引用请说明出处 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty源码解析(一):开始 当前:Netty 源码解析(二): Netty 的 Channel ...
- AOP源码解析之二-创建AOP代理前传,获取AOP信息
AOP源码解析之二-创建AOP代理前传,获取AOP信息. 上篇文章对AOP的基本概念说清楚了,那么接下来的AOP还剩下两个大的步骤获取定义的AOP信息,生成代理对象扔到beanFactory中. 本篇 ...
- 【vuejs深入三】vue源码解析之二 htmlParse解析器的实现
写在前面 一个好的架构需要经过血与火的历练,一个好的工程师需要经过无数项目的摧残. 昨天博主分析了一下在vue中,最为基础核心的api,parse函数,它的作用是将vue的模板字符串转换成ast,从而 ...
- SLF4J源码解析-LoggerFactory(二)
承接前文SLF4J源码解析-LoggerFactory(一),本文则主要针对获取ILoggerFactory对象作下简单的分析 LoggerFactory#getILoggerFactory() 源码 ...
随机推荐
- C#中ESRI.ArcGIS.esriSystem的引用问题
ESRI.ArcGIS.esriSystem,在引用里没有它的同名引用,其实它对应的引用为ESRI.ArcGIS.System,所以添加“ESRI.ArcGIS.System”这个引用即可
- axios中then不用第二个参数,最好用catch
一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法. // bad promise .then(function(data) { // ...
- C++-POJ1020-Anniversary Cake[搜索][dfs]
#include <set> #include <map> #include <cmath> #include <queue> #include < ...
- [AGC027C]ABland Yard
Description AGC027C 给定一张图,点有标号A或B,计算是否对于任意的一个由AB构成的字符串都在图中有对应的路径. Solution 观察可以发现,如果有个环(不一定是简单环)是AAB ...
- 任务队列方案详解(一)JVM线程池
前言 我们都知道 web 服务的工作大多是接受 http 请求,并返回处理后的结果.服务器接受的每一个请求又可以看是一个任务.一般而言这些请求任务会根据请求的先后有序处理,如果请求任务的处理比较耗时, ...
- Java+Selenium+Testng自动化测试学习(二)
Java+Selenium+TestNG自动化测试框架整合 1.简化代码 封装一个定位元素的类,类型为ElementLocation package com.test; import org.open ...
- appium---切换webview时报错
在上一篇中简单介绍了如何查看webview和切换到webview的方法,可能第一次切换webview的时候会报错“Error: session not created exception: Chrom ...
- HDU - 5187 zhx's contest(快速幂+快速乘法)
作为史上最强的刷子之一,zhx的老师让他给学弟(mei)们出n道题.zhx认为第i道题的难度就是i.他想要让这些题目排列起来很漂亮. zhx认为一个漂亮的序列{ai}下列两个条件均需满足. 1:a1. ...
- imread函数+cvtColor()函数
加载图像(用cv::imread) imread功能是加载图像文件成为一个Mat对象,其中第一个参数表示图像文件名称 第二个参数,表示加载的图像是什么类型,支持常见的三个参数值 IMREAD_UNCH ...
- 数据库程序接口——JDBC——API解读第三篇——处理结果集的核心对象
核心对象 处理结果集的核心对象有ResultSet和RowSet.其中ResultSet指定关系型数据库的结果集,RowSet更为抽象,凡是由行列组成的数据都可以. ResultSet ResultS ...