概述

文章对HashMap的部分细节进行介绍,JDK1.7之前有可能出现环形表的问题,而1.7之后进行了改进,文章对环形表现象的出现进行了解析,然后对HashMap注意的几个问题进行了解答。
HashMap的底层实现是数组,主要具有以下特点 :

  • 键值对都允许为空(重要)
  • 线程不安全
  • 不保证有序

问题描述即原因

首先看一下数据迁移的地方在哪里?JDK1.7 HashMap

public V put(K key, V value)
{
......
//算Hash值
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
//如果该key已被插入,则替换掉旧的value (链接操作)
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
//该key不存在,需要增加一个结点
addEntry(hash, key, value, i);
return null;
} //增加一节点
void addEntry(int hash, K key, V value, int bucketIndex)
{
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
//查看当前的size是否超过了我们设定的阈值threshold,如果超过,需要resize
if (size++ >= threshold)
resize(2 * table.length);
} //重新生成空间
void resize(int newCapacity)
{
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
......
//创建一个新的Hash Table
Entry[] newTable = new Entry[newCapacity];
//将Old Hash Table上的数据迁移到New Hash Table上
transfer(newTable);
table = newTable;
threshold = (int)(newCapacity * loadFactor);
} //数据迁移过程
void transfer(Entry[] newTable)
{
Entry[] src = table;
int newCapacity = newTable.length;
//下面这段代码的意思是:
// 从OldTable里摘一个元素出来,然后放到NewTable中
for (int j = 0; j < src.length; j++) {
Entry<K,V> e = src[j];
if (e != null) {
src[j] = null;
do {
Entry<K,V> next = e.next; //NO.1
int i = indexFor(e.hash, newCapacity); //NO.2
e.next = newTable[i]; //NO.3 把当前位置的节点放在新插进来节点的next(于是这里的当前位置在下面一步就会变成久节点了)
newTable[i] = e; //NO.4 当前位置的节点放新插入的节点
e = next; //NO.5 e 换成链表中的下一位
} while (e != null);
}
} }

正常的情况下,下图可以看见久的往后移,新的往前插(饭堂排队吃饭插队一样)

并发情况下,假如有两个线程执行,

  • 线程1执行到 NO.1时
  • 线程2执行完了
    就会出现如下

问题

图片来源与参考资料。

哈希表如何解决Hash冲突

JDK1.7之后换成了尾插法,不会出现环形表的但是依然是线程不安全的。

HashMap 中的 key若 Object类型, 则需实现哪些方法?

参考资料

  • https://www.jianshu.com/p/8324a34577a0

HahMap相关问题的更多相关文章

  1. 嵌入式单片机STM32应用技术(课本)

    目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...

  2. java中的字符串相关知识整理

    字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...

  3. SQL Server相关书籍

    SQL Server相关书籍 (排名不分先后) Microsoft SQL Server 企业级平台管理实践 SQL Server 2008数据库技术内幕 SQL Server性能调优实战 SQL S ...

  4. dotNET跨平台相关文档整理

    一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的平台,在工作之余花了很多时间在M ...

  5. 在ASP.NET Core应用中如何设置和获取与执行环境相关的信息?

    HostingEnvironment是承载应用当前执行环境的描述,它是对所有实现了IHostingEnvironment接口的所有类型以及对应对象的统称.如下面的代码片段所示,一个HostingEnv ...

  6. virtualbox linux虚拟机相关

    linux虚拟机设置为静态IP 在virtualbox中安装好linux虚拟机后,如果采用的是NAT方式的话,linux虚拟机默认采用dhcp方式自动上网,而且用的是NetworkManager服务而 ...

  7. WebGIS中等值面展示的相关方案简析

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 等值面是气象.环保等相关项目上常用到的效果展示.在传统的CS项 ...

  8. .NET同步与异步之相关背景知识(六)

    在之前的五篇随笔中,已经介绍了.NET 类库中实现并行的常见方式及其基本用法,当然.这些基本用法远远不能覆盖所有,也只能作为一个引子出现在这里.以下是前五篇随笔的目录: .NET 同步与异步之封装成T ...

  9. zookeeper集群的搭建以及hadoop ha的相关配置

    1.环境 centos7 hadoop2.6.5 zookeeper3.4.9 jdk1.8 master作为active主机,data1作为standby备用机,三台机器均作为数据节点,yarn资源 ...

随机推荐

  1. luogu P2158 [SDOI2008]仪仗队 (欧拉函数)

    欧拉函数裸题 可惜我太久没做题忘了欧拉函数是什么了... 注意判断一下n = 1的情况就好了 #include <cstdio> using namespace std; ; typede ...

  2. C# Enumerable

    使用Enumerable.Range 打印数字0到9 static void Main(string[] args) { , ); //Range方法获取两个int参数:一个起始数,一个是要生成的结果 ...

  3. ALSA lib编译

    http://blog.sina.com.cn/s/blog_7d7e9d0f0101lqlp.html alsa  lib: #!bin/sh rm -rf ./output/* mkdir -p ...

  4. Dataset: online data

    From Kaggle: Appliances Energy Prediction Energy consumption of the Netherlands International Energy ...

  5. 修复ThinkPHP导出excel数字过大时显示为科学记数法

    修复ThinkPHP导出excel数字过大时显示为科学记数法,这种显示对于查看的用户来说是及其不友好的.所以,我们要使其转化为正常的数字串! 我在google 的过程中,查了一些资料.其中 1).// ...

  6. linux - mysql 异常:MySQL Daemon failed to start.

    报错内容 MySQL Daemon failed to start. 如果直接输入 mysql -root -p 登陆会出现 [mysql]ERROR 2002 (HY000): Can't conn ...

  7. 148.CSRF攻击原理分析、防御、装饰器、中间件、IFrame以及js实现csrf攻击

    CSRF攻击概述: CSRF(Cross Site Request Forgery 跨站域请求伪造)是一种网站攻击的方式,它在2007年曾被列为互联网20大安全隐患之一.其他的安全隐患,比如SQL脚本 ...

  8. hashmap与currentHashMap

    hashmap的缺点 多线程不安全,在并发场景下使用时容易出现死循环,脏读问题等 死循环:https://juejin.im/post/5a66a08d5188253dc3321da0 (这篇好点)h ...

  9. pytorch save model + Gmatch4py + jupyter debugger + community structure

    1. pytorch, 使用训练好的模型测试自己图片 2. [ pytorch ] ——基本使用:(2) 训练好的模型参数的保存以及调用 3. Gmatch4py 4. Network Analysi ...

  10. 一则关于控制文件全部丢失后如何重新编目RMAN元数据的简单实验

    主题:一则简单的RMAN元数据编目实验,来自于博客园AskScuti. 场景:RMAN备份完整情况下,未使用Catalog目录库.删除了所有的控制文件,在手工重建后,导致记录在控制文件中的RMAN备份 ...