Java
java.util
Arrays
HashSet
TreeSet
Deque
ArrayDeque
ArrayList
LinkedBlockingDeque
Map
HashMap
HashTable
TreeMap
LinkedHashMap
ComputeIfAbsent 在jdk8下的死锁场景
synchronized的锁升级过程
Volatile 关键字
redis 中的Lua脚本
AQS - 从干饭角度解析
ConcurrentHashMap
本文档使用 MrDoc 发布
-
+
首页
HashMap
## 描述 Map接口的基于哈希表的实现。 此实现提供所有可选的映射操作,并允许null值和null键。HashMap类大致等同于Hashtable,除了它是非同步的并且允许空值。该类不保证有序。 **如果hashcode扰动后不一致,存储在不同的table[i]中,如果两个元素hashcode扰动一致,视为hash冲突,用拉链法,将table[i]作为List的首元素。链表超过一定大小后,用红黑树改善存取耗时,红黑树超过一定大小时,重新增长table大小,对所有元素重新hash分配。** 此实现为基本操作( get和put )提供O(1),假设散列函数在存储桶中正确分散元素。 迭代集合视图需要的时间与HashMap实例的“容量”(桶的数量)加上它的大小(键值映射的数量)成正比。 因此,如果迭代性能很重要,则不要将初始容量设置得太高(或负载因子太低),这一点非常重要。 HashMap的实例有两个影响其性能的参数:初始容量和负载因子。 容量是哈希表中的桶数,初始容量就是哈希表创建时的容量。 负载因子是衡量哈希表在其容量自动增加之前允许达到多满的指标。 当哈希表中的条目数超过负载因子和当前容量的乘积时,重新哈希表(即重建内部数据结构),使哈希表增长至200%。 如果要在一个HashMap实例中存储许多映射,则创建时指定具有足够的大容量将更有效,而不是让它根据需要自动增长。请注意,使用具有相同hashCode()多个键是降低任何哈希表性能的 **请注意,此实现不是同步的**。 如果多个线程并发访问一个哈希映射,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步。 (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)这通常是通过同步一些自然封装映射的对象来完成的. 如果不存在这样的对象,则应使用Collections.synchronizedMap方法“包装”地图。 这最好在创建时完成,以防止对地图的意外不同步访问: `Map m = Collections.synchronizedMap(new HashMap(...));` ## 底层结构 ``` { // 存储地,长度始终为2的幂 transient Node<K,V>[] table; // 存储个数 transient int size; // 扰动函数,将高16为异或到低16位,让hash更均匀 static final int hash(Object key); // 返回给定容量的二次幂 static final int tableSizeFor(int cap); // 扩容 final Node<K,V>[] resize() } ``` ## 参数 负载因子 = 0.75 初始化长度 = 1 << 4 = 16 最大容量 = 1 << 30 table[i]链表转红黑树阈值 = 8 table[i]红黑树转链表阈值 = 6 table[i]红黑树最大值 = 64 (超过重新调整table容量) 增长比例 = 2 ## 有意思的函数 // 仅无值时可以放置 public V putIfAbsent(K key, V value); // 无值时用默认值 public V getOrDefault(Object key, V defaultValue);
寒烟濡雨
2022年3月29日 21:34
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码