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与JDK1.8.0_66做的分析的更多相关文章

  1. bash: /usr/lib/jvm/jdk1.7.0_80/bin/java: No such file or directory 问题

    在安装java的时候,经常会遇到一些奇奇怪怪的问题. 在配置好环境变量之后,执行java -version,出现: bash: /usr/lib/jvm/jdk1.7.0_80/bin/java: N ...

  2. jdk1.6 升级到 jdk1.7

    将 jdk1.6 升级到 jdk1.7 下载jdk-7u11-linux-x64.tar.gz   tar zxvf  jdk-7u11-linux-x64.tar.gz mkdir   /usr/l ...

  3. Android版数据结构与算法(四):基于哈希表实现HashMap核心源码彻底分析

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 存储键值对我们首先想到HashMap,它的底层基于哈希表,采用数组存储数据,使用链表来解决哈希碰撞,它是线程不安全的,并且存储的key只能有一个为 ...

  4. 基于TILE-GX实现快速数据包处理框架-netlib实现分析【转】

    最近在研究suricata源码,在匹配模式的时候,有tilegx mpipe mode,转载下文,了解一下. 原文地址:http://blog.csdn.net/lhl_blog/article/de ...

  5. StreamDM:基于Spark Streaming、支持在线学习的流式分析算法引擎

    StreamDM:基于Spark Streaming.支持在线学习的流式分析算法引擎 streamDM:Data Mining for Spark Streaming,华为诺亚方舟实验室开源了业界第一 ...

  6. Python爬取《你好李焕英》豆瓣短评并基于SnowNLP做情感分析

    爬取过程在这里: Python爬取你好李焕英豆瓣短评并利用stylecloud制作更酷炫的词云图 本文基于前文爬取生成的douban.txt,基于SnowNLP做情感分析. 依赖库: 豆瓣镜像比较快: ...

  7. jdk1.7.0_80源码包结构

    解压源码src.zip,jdk源码结构如下所示: src |--com.sun    sun公司对jdk的实现,Oracle官方不支持,不保证跨平台(可能一些类linux有而windows没有),甚至 ...

  8. kafka创建topics 错误: 找不到或无法加载主类 Files\Java\jdk1.7.0_80\lib;C:\Program

    解决方案如下: 在kafka安装目录中找到bin\windows目录中的kafka-run-class.bat找到%CLASSPATH%为其加上双引号

  9. jdk完全卸载(亲测jdk1.7.0_80在win7)

    1.从控制面板里删除java程序 2.删除注册表:HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\ 3.删除C:\Windows\System32 和 C:\Windows\ ...

随机推荐

  1. valn 配置

    内核修改: /device drivers/Network device support/MAC-VLAN support 1.创建目录和文件#cd /usr#mkdir vlan#cd vlan#c ...

  2. HAproxy 介绍

    HAproxy 介绍 (1)HAProxy 是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费.快速并且可靠的一种解决方案. HAProxy ...

  3. gradle配置笔记

    apply plugin 使用插件 group 包名 version 项目版本 sourceCompatibility 指定编译.java文件的jdk版本 targetCompatibility 确保 ...

  4. 数独C语言算法

    备好:http://blog.chinaunix.net/uid-26456800-id-3380612.html

  5. ubuntu ssh免密码登录

    目前很多服务(ceph,openstack等)都需要用到SSH使用ssh-key进行登录,而不能使用密码进行登录. 下面是配置步骤: 一.在SSH Client生成ssh key pair root@ ...

  6. Python 元组Tuple概念和操作

    # 元组概念:有序的不可变的元素集合 # 和列表的区别就是, 元组元素不能修改 # 定义 # 一个元素的写法 # (666,) t = (666,) #正确写法 t = (666) #错误写法,括号当 ...

  7. 图片的另一种展现—将后台图片编码直接展现为图片

    1.应用场景            开发过程中,遇到这样的需求:需要将服务器上的图片展现在页面上,但是图片所在服务器不是对外的,图片所在服务器与应用服务器也不在同一台机器上,这时候就需要在开发中先将图 ...

  8. java深入探究14-lucene

    项目代码:链接:http://pan.baidu.com/s/1qXVcfCw 密码:apw1 01 回顾索引 定义:索引是对数据库表中一列或多列的值进行排序的一种结构 目的:加快对数据库表中记录的查 ...

  9. spark学习2-1(hive1.2安装)

    由于前面安装版本过老,导致学习过程中出现了很多问题,今天安装了一个新一点的版本.安装结束启动时遇到一点问题,记录在这里. 第一步:hive-1.2安装 通过WinSCP将apache-hive-1.2 ...

  10. hibernate学习(3)

    0 列表功能实现 1 表与表之间关系回顾 (1)一对多(客户和联系人) (2)多对多(用户和角色) 2 hibernate 一对多操作 (1)一对多映射配置 (2)一对多级联保存 (3)一对多级联删除 ...