关于JDK1.7+中HashMap对红黑树场景的思考
背景
在1.7之前的版本,当数组元素较多(几百、几千,或者更多)的时候,在这种前提扩容,涉及全量元素的遍历和坐标的重新定位,这个耗时会比较长。这是之前存在的一个弊端吧。那么引入红黑树之后就解决了问题,那是怎么解决的呢,我说下自己的理解。
过程分析
既然数组扩容导致了变慢,那就是从扩容方向思考,谁决定了扩容呢?负载因子和数组长度。数组长度是resize自动做的,所以对用户来讲这应该是一个关注不到的变量,那就只剩负载因子了。负载因子越大,扩容的频率就越低。
1. 负载因子较小(小于1)
hash碰撞几率小,当数组元素链表长度达到8个的时候才会转成红黑树,满足这种条件的应该很极端很极端了,与JDK1.7之前的差异其实不大,存在扩容时卡顿。
2. 负载因子较大(大于1)
hash碰撞几率大,所以一个数组元素出现红黑树的几率变大,每个树的数量也会很多。因为扩容的阈值调的比较大,导致轻易不会扩容,整个hashmap更偏向与一颗颗红黑树。扩容就可以理解为对红黑树的维护,达到了丝般顺滑的效果。
总结
根据前面的分析,引入红黑树主要好处有2个:
- 极端情况下,保证hashmap碰撞过多的元素的高性能操作。
- 负载因子变大情况,使hashmap倾向于一个红黑树的数组,带来的好处就是对元素的操作时间复杂度的整体稳定。
本质上还是得具体场景的权衡,如果数组太大,扩容会导致外部调用超时那就选择调大负载因子,达到削峰的目的。否则维持以前的用法就可以了,
完。
关于JDK1.7+中HashMap对红黑树场景的思考的更多相关文章
- JDK1.8中HashMap实现
JDK1.8中的HashMap实现跟JDK1.7中的实现有很大差别.下面分析JDK1.8中的实现,主要看put和get方法. 构造方法的时候并没有初始化,而是在第一次put的时候初始化 putVal方 ...
- JDK1.7中HashMap死环问题及JDK1.8中对HashMap的优化源码详解
一.JDK1.7中HashMap扩容死锁问题 我们首先来看一下JDK1.7中put方法的源码 我们打开addEntry方法如下,它会判断数组当前容量是否已经超过的阈值,例如假设当前的数组容量是16,加 ...
- 怎样的操作才能让HashMap以红黑树类型存储数据? (文中没有解答该问题)
怎样才能让HashMap以红黑树类型存储数据? 看上面的代码可知:如果一个Node的长度大于等于7.就会触发Node转TreeNode的操作. 我向一个map中插入了一百万条数据(插入一亿条时,内存溢 ...
- 浅析Java源码之HashMap外传-红黑树Treenode(已鸽)
(这篇文章暂时鸽了,有点理解不能,点进来的小伙伴可以撤了) 刚开始准备在HashMap中直接把红黑树也过了的,结果发现这个类不是一般的麻烦,所以单独开一篇. 由于红黑树之前完全没接触过,所以这篇博客相 ...
- 为什么HashMap使用红黑树而不使用AVL树
为什么HashMap使用红黑树而不使用AVL树? 红黑树适用于大量插入和删除:因为它是非严格的平衡树:只要从根节点到叶子节点的最长路径不超过最短路径的2倍,就不用进行平衡调节 AVL 树是严格的平衡树 ...
- 【Java源码】集合类-JDK1.8 哈希表-红黑树-HashMap总结
JDK 1.8 HashMap是数组+链表+红黑树实现的,在阅读HashMap的源码之前先来回顾一下大学课本数据结构中的哈希表和红黑树. 什么是哈希表? 在存储结构中,关键值key通过一种关系f和唯一 ...
- JDK1.7中HashMap底层实现原理
一.数据结构 HashMap中的数据结构是数组+单链表的组合,以键值对(key-value)的形式存储元素的,通过put()和get()方法储存和获取对象. (方块表示Entry对象,横排表示数组ta ...
- java随笔——HashMap与红黑树
前言: hashmap是一种很常用的数据结构,其使用方便快捷,接下来笔者将给大家深入解析这个数据结构,让大家能在用的时候知其然,也知其所以然. 一.Map 首先,从最基本的讲起,我们先来认识一下map ...
- HashMap之红黑树
红黑树的设计,相比 jdk1.7 的 HashMap 而言,jdk1.8 最重要的就是引入了红黑树的设计,当冲突的链表长度超过 8 个的时候,链表结构就会转为红黑树结构. 01.故事的起因 “ JDK ...
随机推荐
- 数据库升级到mysql5.7出现的1067 - Invalid default value for '字段名' (docker版)
docker run -d --name xxx mysql:5.7 docker container cp xxx:/etc/mysql/mysql.conf.d . // 取出mysql中的配 ...
- 前端部署ant+yuicompressor文件压缩+获取版本+SSH公布(部分代码)
文件压缩: <apply executable="java" parallel="false" failonerror="true" ...
- MySQL replace into (insert into 的增强版)
在使用SQL语句进行数据表插入insert操作时,如果表中定义了主键,插入具有相同主键的记录会报错: Error Code: 1062. Duplicate entry 'XXXXX' for ke ...
- 教程一 openwrt路由器入门 远程命令行+文件系统
如图,拿到一个openwrt路由器我们第一步要远程控制. 这里在买了两块wifi-robots wifi视频模块. 0首先说下这个WIIF的信息 淘宝购买链接 https://item.taobao ...
- pytorch的函数中的group参数的作用
1.当设置group=1时: conv = nn.Conv2d(in_channels=, out_channels=, kernel_size=, groups=) conv.weight.data ...
- Jenkins + Ansible + Gitlab之gitlab篇
前言 持续交付 版本控制器:Gitlab.GitHub 持续集成工具:jenkins 部署工具:ansible 课程安排 Gitlab搭建与流程使用 Ansible环境配置与Playbook编写规范 ...
- Springboot + Atomikos + Druid + Mysql 实现JTA分布式事务
DataSource 配置 package com.cheng.dynamic.config; import java.util.Properties; import javax.sql.DataSo ...
- 类Objects
Object类是什么? 在JDK7添加了一个Objects工具类,它提供了一些方法来操作对象,它由一些静态的实用方法组成,这些方法是null-save(空指针安全的)或null-tolerant(容忍 ...
- JSP中常用的的EL表达式的汇总
Jsp基础知识 jsp的组成 html静态页面(css.javascript) java代码 <% %> (_jspService方法中) 内置对象 out request 表达式 < ...
- Redis之持久化(RDB AOF)
Redis 提供了 RDB 和 AOF 两种持久化方案: RDB:生成指定时间间隔内的 Redis 内存中数据快照,是一个二进制文件 dumpr.rdb AOF:记录 Redis 除了查询以外的所有写 ...