hashMap 数据结构

如上图所示,JDK7之前hashmap又叫散列链表:基于一个数组以及多个链表的实现,hash值冲突的时候,就将对应节点以链表的形式存储。

JDK8中,当同一个hash值(Table上元素)的链表节点数不小于8时,将不再以单链表的形式存储了,会被调整成一颗红黑树。这就是JDK7与JDK8中HashMap实现的最大区别。

其下基于 JDK1.7.0_80 JDK1.8.0_66 做的分析

JDK1.7中

使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到数组里的位置,如果hashcode相同,或者hashcode取模后的结果相同(hash collision),那么这些key会被定位到Entry数组的同一个格子里,这些key会形成一个链表。

在hashcode特别差的情况下,比方说所有key的hashcode都相同,这个链表可能会很长,那么put/get操作都可能需要遍历这个链表

也就是说时间复杂度在最差情况下会退化到O(n)

JDK1.8中

使用一个Node数组来存储数据,但这个Node可能是链表结构,也可能是红黑树结构

如果插入的key的hashcode相同,那么这些key也会被定位到Node数组的同一个格子里。

如果同一个格子里的key不超过8个,使用链表结构存储。

如果超过了8个,那么会调用treeifyBin函数,将链表转换为红黑树。

那么即使hashcode完全相同,由于红黑树的特点,查找某个特定元素,也只需要O(log n)的开销

也就是说put/get的操作的时间复杂度最差只有O(log n)

听起来挺不错,但是真正想要利用JDK1.8的好处,有一个限制:

key的对象,必须正确的实现了Compare接口

如果没有实现Compare接口,或者实现得不正确(比方说所有Compare方法都返回0)

那JDK1.8的HashMap其实还是慢于JDK1.7的

简单的测试数据如下:

向HashMap中put/get 1w条hashcode相同的对象

JDK1.7:                                  put 0.26s,get 0.55s

JDK1.8(未实现Compare接口):put 0.92s,get 2.1s

但是如果正确的实现了Compare接口,那么JDK1.8中的HashMap的性能有巨大提升,这次put/get 100W条hashcode相同的对象

JDK1.8(正确实现Compare接口,):put/get大概开销都在320ms左右

为什么要这么操作呢?

我认为应该是为了避免Hash Collision DoS攻击

Java中String的hashcode函数的强度很弱,有心人可以很容易的构造出大量hashcode相同的String对象。

如果向服务器一次提交数万个hashcode相同的字符串参数,那么可以很容易的卡死JDK1.7版本的服务器。

但是String正确的实现了Compare接口,因此在JDK1.8版本的服务器上,Hash Collision DoS不会造成不可承受的开销。

参考资料:

jdk1.7.0_80的HashMap源码

jdk1.8.0_66的HashMap源码

Java 8系列之重新认识HashMap

HASH COLLISION DOS 问题

部分转载自:http://www.cnblogs.com/stevenczp/p/7028071.html

HashMap 在 Java1.7 与 1.8 中的区别的更多相关文章

  1. HashMap在Java1.7与1.8中的区别

    基于JDK1.7.0_80与JDK1.8.0_66做的分析 JDK1.7中 使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到数组里的位置,如果hashcode相同, ...

  2. java中 HashMap和Hashtable,list、set和map 的区别

    摘自: http://blog.chinaunix.net/uid-7374279-id-2057584.html HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Ma ...

  3. JDK1.7中HashMap死环问题及JDK1.8中对HashMap的优化源码详解

    一.JDK1.7中HashMap扩容死锁问题 我们首先来看一下JDK1.7中put方法的源码 我们打开addEntry方法如下,它会判断数组当前容量是否已经超过的阈值,例如假设当前的数组容量是16,加 ...

  4. 【转】HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap区别

    转自:http://blog.csdn.net/paincupid/article/details/47746341 一.HashMap和TreeMap区别 1.HashMap是基于散列表实现的,时间 ...

  5. 集合 HashMap 的原理,与 Hashtable、ConcurrentHashMap 的区别

    一.HashMap 的原理 1.HashMap简介 简单来讲,HashMap底层是由数组+链表的形式实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表 ...

  6. js中== 和===中的区别

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  7. continue语句在for语句和while语句中的区别

    while语句的形式: while( expression ) statement for语句的形式: for( expression1; expression2;expression3 )   // ...

  8. Objective-C声明在头文件和实现文件中的区别

    Objective-C声明在头文件和实现文件中的区别 转自codecloud(有整理) 调试程序的时候,突然想到这个问题,百度一下发现有不少这方面的问答,粗略总结一下: 属性写在.h文件中和在.m文件 ...

  9. 在oracle中where 子句和having子句中的区别

    在oracle中where 子句和having子句中的区别 1.where 不能放在GROUP BY 后面 2.HAVING 是跟GROUP BY 连在一起用的,放在GROUP BY 后面,此时的作用 ...

随机推荐

  1. js原型解释图

  2. 2016/2/13 《计算机系统要素》(The Elements of Computing Systems)读书笔记(1)

    过年期间一直在啃一本书,学习计算机组成原理. 这是一本很棒的书,是一个基于项目的学习过程.可以让人理解的很深刻. coursera上有这本书前半部分的教程,是由书的作者团队们开的课,个人认为很棒,可惜 ...

  3. Jenkins配置定时任务

    在任务配置中,滚动到构建触发器-->勾选"Build periodically"-->在输入框中配置触发时间 以上配置,表示在6月13日23点触发. 如果配置成  00 ...

  4. PHP面向对象__set(赋值方法)

    //类Ren里面的变量都是私有的,子类$r里面直接取是取不到的,正常给变量赋值的方法为$r->__set("age",20);,但是可以直接写成$r->age = 20 ...

  5. redis写定时任务获取root权限

    前提: 1.redis由root用户启动. 2.开启cron的时候,/var/spool/cron linux机器下默认的计划任务,linux会定时去执行里面的任务. 启动服务 :/sbin/serv ...

  6. Shell编程之运算符和环境变量配置文件

    一.shell运算符:    declare命令:         declare    -i 变量名     #声明变量        eg. movie[o]=dzp     #定义数组      ...

  7. NYOJ 116 士兵杀敌(二) (树状数组)

    题目链接 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的.小工是南将军手下的军师,南将军经常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧.南将军的某次询问之后 ...

  8. Django-数据库增查

    1/ python manage.py shell ---------一般用于调试操作 2/ 建表--定义类 #产品表 class ProductModel(models.Model): #通过类属性 ...

  9. JS踩过的坑

    一:DOM对象的查找 DOM的查找到的对象,除byID的之外,返回的都是一个数组,并不是DOM对象无法调用DOM对象的方法. 通过id查找: 因为id在一个HTML文件中唯一,因此查找到的只会是一个元 ...

  10. 在Django中Session的那点事!

    1.session是什么 首先引入度娘的解释:Session:在计算机中,尤其是在网络应用中,称为“会话控制”.Session 对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序的 We ...