网站大量收购独家精品文档,联系QQ:2885784924

Java集合深入理解HashMap主要特点和关键方法源码解读.doc

Java集合深入理解HashMap主要特点和关键方法源码解读.doc

  1. 1、本文档共22页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Java集合深入理解HashMap主要特点和关键方法源码解读

Java 集合深入理解(16):HashMap 主要特点和关键方法源码解读 什么是 HashMap HashMap 是一个采用哈希表实现的键值对集合,继承自?AbstractMap,实现了?Map 接口?。? HashMap 的特殊存储结构使得在获取指定元素前需要经过哈希运算,得到目标元素在哈希表中的位置,然后再进行少量比较即可得到元素,这使得 HashMap 的查找效率贼高。 当发生 哈希冲突(碰撞)的时候,HashMap 采用?拉链法?进行解决(不熟悉 “哈希冲突” 和 “拉链法” 这 2 个概念的同学可以点这里了解),因此 HashMap 的底层实现是?数组+链表,如下图 所示: HashMap 的特点 结合平时使用,可以了解到 HashMap 大概具有以下特点: 底层实现是 链表数组,JDK 8 后又加了 红黑树 实现了 Map 全部的方法 key 用 Set 存放,所以想做到?key 不允许重复,key 对应的类需要重写 hashCode 和 equals 方法 允许空键和空值(但空键只有一个,且放在第一位,下面会介绍) 元素是无序的,而且顺序会不定时改变 插入、获取的时间复杂度基本是 O(1)(前提是有适当的哈希函数,让元素分布在均匀的位置) 遍历整个 Map 需要的时间与 桶(数组) 的长度成正比(因此初始化时 HashMap 的容量不宜太大) 两个关键因子:初始容量、加载因子 除了不允许 null 并且同步,Hashtable 几乎和他一样。 下面结合源码进行验证这些特点。 HashMap 的 13 个成员变量 1.默认初始容量:16,必须是 2 的整数次方 static final int DEFAULT_INITIAL_CAPACITY = 1 4; 2.默认加载因子的大小:0.75,可不是随便的,结合时间和空间效率考虑得到的 static final float DEFAULT_LOAD_FACTOR = 0.75f; 3.最大容量: 2^ 30 次方 static final int MAXIMUM_CAPACITY = 1 30; 4.当前 HashMap 修改的次数,这个变量用来保证?fail-fast?机制 transient int modCount; 5.阈值,下次需要扩容时的值,等于 容量*加载因子 int threshold; 6.树形阈值:JDK 1.8 新增的,当使用 树 而不是列表来作为桶时使用。必须必 2 大 static final int TREEIFY_THRESHOLD = 8; 7.非树形阈值:也是 1.8 新增的,扩容时分裂一个树形桶的阈值(?不是很懂 - -),要比 TREEIFY_THRESHOLD 小 static final int UNTREEIFY_THRESHOLD = 6; 8.树形最小容量:桶可能是树的哈希表的最小容量。至少是 TREEIFY_THRESHOLD 的 4 倍,这样能避免扩容时的冲突 static final int MIN_TREEIFY_CAPACITY = 64; 9.缓存的 键值对集合(另外两个视图:keySet 和 values 是在?AbstractMap?中声明的) transient SetMap.EntryK,V entrySet; 10.哈希表中的链表数组 transient NodeK,V[] table; 11.键值对的数量 transient int size; 12.哈希表的加载因子 final float loadFactor; HashMap 的初始容量和加载因子 由于 HashMap 扩容开销很大(需要创建新数组、重新哈希、分配等等),因此与扩容相关的两个因素: 容量:数组的数量 加载因子:决定了 HashMap 中的元素占有多少比例时扩容 成为了 HashMap 最重要的部分之一,它们决定了 HashMap 什么时候扩容。 HashMap 的默认加载因子为 0.75,这是在时间、空间两方面均衡考虑下的结果: 加载因子太大的话桶太多,遍历时效率变低 太小的话频繁 rehash,导致性能降低 当设置初始容量时,需要提前考虑 Map 中可能有多少对键值对,设计合理的加载因子,尽可能避免进行扩容。 如果存储的键值对很多,干脆设置个大点的容量,这样可以少扩容几次。 HashMap 的关键方法 1. HashMap 的 4 个构造方法 //创建一个空的哈希表,初始容量为 16,加载因子为 0.75 public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted } //创建一个空的哈希表,指

文档评论(0)

haihang2017 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档