hashmap源码解析,JDK1.8和1.7的区别
背景:hashmap面试基础必考内容,需要深入了解,并学习其中的相关原理。此处还要明白1.7和1.8不通版本的优化点。
Java 8系列之重新认识HashMap
鉴于JDK1.8做了多方面的优化,总体性能优于JDK1.7,下面我们从两个方面用例子证明这一点(在hash均匀和不均匀的情况下性能都有明显的提升)
不管增加、删除、查找键值对,定位到哈希桶数组的位置都是很关键的第一步。前面说过HashMap的数据结构是数组和链表的结合,所以我们当然希望这个HashMap里面的元素位置尽量分布均匀些,尽量使得每个位置上的元素数量只有一个,那么当我们用hash算法求得这个位置的时候,马上就可以知道对应位置的元素就是我们要的,不用遍历链表,大大优化了查询的效率。HashMap定位数组索引位置,直接决定了hash方法的离散性能。先看看源码的实现(方法一+方法二):
方法一:
static final int hash(Object key) { //jdk1.8 & jdk1.7
int h;
// h = key.hashCode() 为第一步 取hashCode值
// h ^ (h >>> 16) 为第二步 高位参与运算
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
方法二:
static int indexFor(int h, int length) { //jdk1.7的源码,jdk1.8没有这个方法,但是实现原理一样的
return h & (length-1); //第三步 取模运算
}
这里的Hash算法本质上就是三步:取key的hashCode值、高位运算、取模运算。
对于任意给定的对象,只要它的hashCode()返回值相同,那么程序调用方法一所计算得到的Hash码值总是相同的。我们首先想到的就是把hash值对数组长度取模运算,这样一来,元素的分布相对来说是比较均匀的。但是,模运算的消耗还是比较大的,在HashMap中是这样做的:调用方法二来计算该对象应该保存在table数组的哪个索引处。
这个方法非常巧妙,它通过h & (table.length -1)来得到该对象的保存位,而HashMap底层数组的长度总是2的n次方,这是HashMap在速度上的优化。当length总是2的n次方时,h& (length-1)运算等价于对length取模,也就是h%length,但是&比%具有更高的效率。
在JDK1.8的实现中,优化了高位运算的算法,通过hashCode()的高16位异或低16位实现的:(h = k.hashCode()) ^ (h >>> 16),主要是从速度、功效、质量来考虑的,这么做可以在数组table的length比较小的时候,也能保证考虑到高低Bit都参与到Hash的计算中,同时不会有太大的开销。
Java源码分析:HashMap 1.8 相对于1.7 到底更新了什么?
Java源码分析:HashMap 1.8 相对于1.7 到底更新了什么?
ps超详细的 太牛逼了 好好读读
1.8不会出现1.7的多线程环形链死循环情况,但是还不是线程安全的,因为没有同步锁。
jdk1.8与1.7之间 hashmap的不同,优化点!!
所有处理的根本目的,都是为了提高 存储key-value的数组下标位置 的随机性 & 分布均匀性,尽量避免出现hash值冲突。即:对于不同key,存储的数组下标位置要尽可能不一样
JDK 1.8 的优化目的主要是:减少 Hash冲突 & 提高哈希表的存、取效率
hashmap源码解析,JDK1.8和1.7的区别的更多相关文章
- HashMap源码解析、jdk7和8之后的区别、相关问题分析(多线程扩容带来的死循环)
一.概览 HashMap<String, Integer> map = new HashMap<>(); 这个语句执行起来,在 jdk1.8 之前,会创建一个长度是 16 的 ...
- Map集合类(一.hashMap源码解析jdk1.8)
java集合笔记一 java集合笔记二 java集合笔记三 jdk 8 之前,其内部是由数组+链表来实现的,而 jdk 8 对于链表长度超过 8 的链表将转储为红黑树 1.属性 //节点数组,第一次使 ...
- 最全的HashMap源码解析!
HashMap源码解析 HashMap采用键值对形式的存储结构,每个key对应唯一的value,查询和修改的速度很快,能到到O(1)的平均复杂度.他是非线程安全的,且不能保证元素的存储顺序. 他的关系 ...
- HashMap源码解析和设计解读
HashMap源码解析 想要理解HashMap底层数据的存储形式,底层原理,最好的形式就是读它的源码,但是说实话,源码的注释说明全是英文,英文不是非常好的朋友读起来真的非常吃力,我基本上看了差不多 ...
- 【转】Java HashMap 源码解析(好文章)
.fluid-width-video-wrapper { width: 100%; position: relative; padding: 0; } .fluid-width-video-wra ...
- HashMap源码解析 非原创
Stack过时的类,使用Deque重新实现. HashCode和equals的关系 HashCode为hash码,用于散列数组中的存储时HashMap进行散列映射. equals方法适用于比较两个对象 ...
- 死磕Java之聊聊HashMap源码(基于JDK1.8)
死磕Java之聊聊HashMap源码(基于JDK1.8) http://cmsblogs.com/?p=4731 为什么面试要问hashmap 的原理
- Java中的容器(集合)之HashMap源码解析
1.HashMap源码解析(JDK8) 基础原理: 对比上一篇<Java中的容器(集合)之ArrayList源码解析>而言,本篇只解析HashMap常用的核心方法的源码. HashMap是 ...
- 详解HashMap源码解析(下)
上文详解HashMap源码解析(上)介绍了HashMap整体介绍了一下数据结构,主要属性字段,获取数组的索引下标,以及几个构造方法.本文重点讲解元素的添加.查找.扩容等主要方法. 添加元素 put(K ...
- 给jdk写注释系列之jdk1.6容器(4)-HashMap源码解析
前面了解了jdk容器中的两种List,回忆一下怎么从list中取值(也就是做查询),是通过index索引位置对不对,由于存入list的元素时安装插入顺序存储的,所以index索引也就是插入的次序. M ...
随机推荐
- python 根据字符串语句进行操作再造函数(evec和eval方法)
例: #coding:utf-8 ''' Created on 2017年9月9日 @author: Bss ''' test_list=['def','a',''] test_list1=['pri ...
- postgres —— 窗口函数入门
注:测试数据在 postgres —— 分组集与部分聚集 中 聚集将多行转变成较少.聚集的行.而窗口则不同,它把当前行与分组中的所有行对比,并且返回的行数没有变化. 组合当前行与 production ...
- Flume 概述/企业案例
概述 1 Flume定义 Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统.Flume基于流式架构,灵活简单. 下面我们来详细介绍一下Flume架构中的 ...
- 学习:C++中的头文件和源文件详解
一.C++编译模式: 通常,在一个C++程序中,只包含两类文件――.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是 ...
- POJ P1985 Cow Marathon 题解
这道题是我们考试的第一题,非常水,就是一个树的直径的板子.详见上一篇博客. #include<iostream> #include<cstdio> #include<cs ...
- learning java Charset 查看支持的字符集类型
import java.nio.charset.Charset; import java.util.SortedMap; public class CharsetTest { public stati ...
- 【loj2985】【WC2019】I君的商店
题目 交互题: 有\(n\)个物品,每个物品的价格为0或者1; 给出为1的物品的个数奇偶性k,并保证至少有一个价格为1: 每次可以询问一个集合S的另一个集合T的价值和的大小,交互库会返回>=或者 ...
- Comparison of SIFT Encoded and Deep Learning Features for the Classification and Detection of Esca Disease in Bordeaux Vineyards(分类MobileNet,目标检测 RetinaNet)
识别葡萄的一种虫害,比较了传统SIFT和深度学习分类,最后还做了目标检测 分类用的 MobileNet,目标检测 RetinaNet MobileNet 是将传统深度可分离卷积分成了两步,深度卷积和逐 ...
- mysql count() 函数,对结果统计计数
mysql> ; +----------+------------+-----+---------------------+ | name_new | transactor | pid | or ...
- mysql .字符串转日期
insert into share (uid, mapId, isdir, type, pwd, shareTime, overTime, price) values (1, 10, 0, 1,&qu ...