上文讲到HashMap的增加方法,现在继续 上文链接

HashMap在上一篇源码分析的文章中,如果使用put的时候如果元素数量超过threshold就会调用resize进行扩容

1.扩容机制

想要了解HashMap的扩容机制你要有这两个问题

  • 1.什么时候才需要扩容
  • 2.HashMap的扩容是什么

在添加元素的时候如果超过threshold设置的阀值点就会进行扩容,简单的来说就是一个水壶容量是二升,然后这个时候已经满了但是你还要继续加水,咋办?换个大的。所以HashMap的扩容就和你这个水壶一样,水已经满了那我就在换个大的水壶继续加水。不过在你换水壶的时候是有很多条件的。

在我看这个resize的源码的时候我也是一脸懵逼,最后请教了大佬得到的回答是因为1.8加入了红黑树比较麻烦可以看一下1.7的,然后我有去网上看了一下别人写的文章基本上都是基于1.7的resize。所以这里就看1.7的resize来分析。

来看JDK1.7中resize的实现。

复制操作是调用的transfer方法

在1.7中的resize结合一下我们的小例子可以这样理解,去超市买一个大一点的水壶,然后把以前水壶里面的水给倒进新的水壶里面。再把我们当前的水壶的容量替换掉,告诉别人我的容量更大了。(强行比喻哈哈哈哈哈)

1.7中的resize就是这么简单,那我们在看一下1.8中的resize(),这样再看就不会一脸懵逼了

我在这里把1.8的resize方法分为两部分

  • 1.计算新的newCap(新的容量)和newThr(新阀值点)
  • 2.复制新的数组

第一部分

第二部分

对比一下1.7

  • 1.7元素不需要更换位置。1.8元素的位置要么是在原位置,要么是在原位置再移动2次幂的位置
  • 不需要像1.7一样重新计算hash

2.删除

删除的话就是首先先找到元素的位置,如果是链表就遍历链表找到元素之后删除。如果是用红黑树就遍历树然后找到之后做删除,树小于6的时候要转链表。

删除方法:

调用removeNode:

3.查找元素

查找方法,通过元素的Key找到Value。

调用getNode()方法

看完可以知道逻辑是先通过Key计算出索引的位置,然后先检查第一个节点看看是否是我们要的节点,如果不是在去查看是否死红黑树和链表。

4.遍历

我们通过下面几个例子来演示一下HashMap怎么遍历

1.分别遍历Key和Values

 		for (String key:map.keySet()){
System.out.println(key);
}
for (Object value : map.values()) {
System.out.println(value);
}

2.迭代

 		Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> mapEntry = iterator.next();
System.out.println(mapEntry.getKey() + "====" + mapEntry.getValue());
}

3.获取 key 集合

 	Set<String> keySet = map.keySet();
for (String str : keySet) {
System.out.println(str + "====" + map.get(str));
}

4.获取Entry 集合,遍历Entry 集合

	Set<Map.Entry<String, Object>> entrySet = map.entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
System.out.println(entry.getKey() + "====" + entry.getValue());
}

对比来说使用迭代的方式是最好的,也可以在迭代的时候对集合的元素进行删除

总结

基于JDK1.8的HashMap是由数组+链表+红黑树组成,当链表长度超过 8 时会自动转换成红黑树,当红黑树节点个数小于 6 时,又会转化成链表。相对于早期版本的 JDK HashMap 实现,新增了红黑树作为底层数据结构,在数据量较大且哈希碰撞较多时,能够极大的增加检索的效率。HashMap并不是线程安全的,支持K和V为null ,k重复会覆盖,V可以重复,还有一点HashMap遍历的数据不是有序的是无序的

HashMap源码分析(二):看完彻底了解HashMap的更多相关文章

  1. JAVA源码分析-HashMap源码分析(二)

    本文继续分析HashMap的源码.本文的重点是resize()方法和HashMap中其他的一些方法,希望各位提出宝贵的意见. 话不多说,咱们上源码. final Node<K,V>[] r ...

  2. HashMap源码分析二

    jdk1.2中HashMap的源码和jdk1.3中HashMap的源码基本上没变.在上篇中,我纠结的那个11和101的问题,在这边中找到答案了.   jdk1.2   public HashMap() ...

  3. HashMap源码分析(史上最详细的源码分析)

    HashMap简介 HashMap是开发中使用频率最高的用于映射(键值对 key value)处理的数据结构,我们经常把hashMap数据结构叫做散列链表: ObjectI entry<Key, ...

  4. 十、Spring之BeanFactory源码分析(二)

    Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...

  5. 源码分析系列1:HashMap源码分析(基于JDK1.8)

    1.HashMap的底层实现图示 如上图所示: HashMap底层是由  数组+(链表)+(红黑树) 组成,每个存储在HashMap中的键值对都存放在一个Node节点之中,其中包含了Key-Value ...

  6. 【JAVA集合】HashMap源码分析(转载)

    原文出处:http://www.cnblogs.com/chenpi/p/5280304.html 以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储 ...

  7. Java中HashMap源码分析

    一.HashMap概述 HashMap基于哈希表的Map接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.(除了不同步和允许使用null之外,HashMap类与Hashtab ...

  8. 【Java】HashMap源码分析——常用方法详解

    上一篇介绍了HashMap的基本概念,这一篇着重介绍HasHMap中的一些常用方法:put()get()**resize()** 首先介绍resize()这个方法,在我看来这是HashMap中一个非常 ...

  9. Java源码解析——集合框架(五)——HashMap源码分析

    HashMap源码分析 HashMap的底层实现是面试中问到最多的,其原理也更加复杂,涉及的知识也越多,在项目中的使用也最多.因此清晰分析出其底层源码对于深刻理解其实现有重要的意义,jdk1.8之后其 ...

随机推荐

  1. String的本质是一个char*,只是以类的形式提供,使用起来比较方便

    String的本质是一个char*,只是以类的形式提供,使用起来比较方便 Class String {private: char* m_data;}摘自<后台开发 核心技术与应用实践__徐晓鑫& ...

  2. sqlserver创建接受任何类型的nvl

    if exists ( select * from sys.objects where object_id = object_id(N'dbo.nvl') and type = N'FN') begi ...

  3. Win10《芒果TV》更新v3.6.0秋收版:新增追剧磁贴、记忆续播、跳转列表

    热血青春,唱响革命战歌,<秋收起义>正在芒果TV热播,Win10版<芒果TV>更新v3.6.0秋收版,新增追剧磁贴.记忆续播.跳转列表. Win10版<芒果TV>V ...

  4. 微信小程序把玩(八)view组件

    原文:微信小程序把玩(八)view组件 刚看到这个效果的时候还真是和ReactNative的效果一致,属性也基本的一样. view这个组件就是一个视图组件使用起来非常简单. 主要属性: flex-di ...

  5. 如何作为一个优秀的ERP实施顾问

    原文地址:如何作为一个优秀的ERP实施顾问作者:天思软件 作一个优秀的ERP实施顾问无论是天思.金蝶,用友,还是其他业务软件.实施顾问的发展道路都差不多. 1.初级实施顾问,中级实施顾问,高级实施顾问 ...

  6. 网络软件,BA File,Disk,Photo,BackupTools等等(Mac版)

    Auto FTP Manager 6.01Crossworld CrossFTP Enterprise v1.97.7 http://www.airexplorer.net/en/index.phpC ...

  7. 学习Java,值得你留意的问题(1)更名为《学习Java,容易被你忽略的小细节(1)》

    记得大二快要结束的时候,有个女孩子突然问我“你会Java吗,帮我做大作业好吗?” 实话说,那个女孩真的很漂亮,我当时也非常想帮她.但是我从来没有接触过Java,让我在短短的几天内完成Java程序设计课 ...

  8. Kafka笔记7

    Kafka提供了一些命令行工具,用于管理集群变更.这些工具使用Java实现,Kafka提供了一些脚本调用这些Java类. 9.1主题操作 使用Kafka-topics.sh工具可以执行主题大部分工作, ...

  9. springboot读取本地项目文件

    在读取springBoot+gradle构建的项目时,如果使用传统的FileInputStream读取文件流或者ResourceUtils工具类的方式 File file= ResourceUtils ...

  10. Hive学习之路(二)—— Linux环境下Hive的安装部署

    一.安装Hive 1.1 下载并解压 下载所需版本的Hive,这里我下载版本为cdh5.15.2.下载地址:http://archive.cloudera.com/cdh5/cdh/5/ # 下载后进 ...