关于HashMap的一些常见的问题,自己总结一下:

首选HashMap在jdk1.7和jdk1.8里面的实现是不同的,在jdk1.7中HashMap的底层实现是通过数组+链表的形式实现的,在jdk1.8中HashMap的底层是通过数组+链表+红黑树来实现的。

Question1: 数组链表是怎么切换的(1.7)?

答:在put的时候采用hash(key)&(len-1)来计算数据存放的index,以此存放元素。当出现哈希冲突的时候,因为有限的数组长度,遭遇哈希冲突,此时就可以使用链表来存储哈希值相同但是值不同的对象。

Question2:Entry节点如何插入链表(1.7)?

答: Entry节点插入链表是使用头插法来实现的,主要的实现是通过其CreateEntry来实现的,Entry的构造方法中可以协助头插的顺利进行,使用头插法是考虑到热点数据的问题,当时的想法是最近插入的元素,最近也可能被使用,头插入的实现可以缩短链表查找元素的时间。

Question3:jdk1.8以后为什么改用尾插入?

答:根据initialCapacity*LoadFactoor=capacity以后,如果插入的元素容量达到了capacity,此时会进行扩容,扩容操作按照源码中的写法,主要有两步:1.扩容一个新的Entry,容量为原来的两倍。2.进行Rehash操作,将原来的数据复制到新的Entry中。(1.7)如果是头插入的话,当多线程处理的时候,此时如果存在a->b->c链表,当我们rehash以后,有可能变为b->a,然而其他的线程处理完之后,结果可能会造成b->a->b,造成loop成环。一旦寻找数据会造成死循环。

而1.8以后改成尾插入以后,源码中使用了一个高位来识别之前的数据和插入的新数据,保持了之前的顺序,解决了1.7中可能造成成环的问题。具体的实现是扩容只有最高位会多出一个1,如果之前的数据一旦e & oldCapacity = 0,表明是原来的数据,保持就好,如果是为1,表明是即将插入的新数据,此时保持插入高位,这样就避免了成环的问题。

Question4:为什么要进行Rehash操作?

答: 因为此时的长度遍历按照index=hashcode & (len - 1)的计算,此时的规则变了,所以需要进行rehash操作。

Question5:HashMap为什么不是线程安全?

答:在jdk1.7中即使不出现死循环,由于put操作未加锁,我们也不能确保对于多个线程同时执行put操作时,上一秒修改完的put的值,下一秒get是否是修改后的值,容易被其他线程的值所覆盖,线程安全无法保证(1.7&1.8都是如此)

Question6:为啥源码的容量初始化大小为16?

答:在源码中有个方法叫做tableSizeFor(),这个方法是为了将当前的容量扩容到一个距离当前容量的2的整次方幂。阿里巴巴手册上也建议使用HashMap需要设置一个初始化的容量值,一般来说是设置为16,为什么是16而不是8或者4,因为4或者8容易导致hashMap扩容,影响性能。只要输入的HashCode分布是相对均匀的,那么hash算法就是均匀的,所以给16主要也是为了实现均匀分布。

Question7:为啥重写equals方法的同时需要重写hashCode方法?使用HashMap举例子说明?

答: 首先,equals方法继承了Object的equals方法,比较的对于值对象比较的是两个对象的值是否相等,对于引用对象比较的是两个对象的内存地址是否相等。上面也说到HashMap是通过hash(key)&(len-1)去寻找index的,index相同就形成链表存储数据,但是假如一个index中存储了object1、object2对象,他们的hash值相同,此时如果我们get数据object2,get(key)此时将会有两个值,你怎么能确保获取到的是object2而不是object1,此时就需要使用equals来比较对象的key是否相同,这样才可以获取到对的对象。实质上在底层get方法的实现是通过getNode(hash(key),key)来实现的,前面的是hash值,后面的是equals对比的对象。

Question8:HashMap线程不安全不适合多线程,那用什么可以替代?

答:可以使用HashTable或者ConcurrentHashMap来替代HashMap,但是HashTable仅仅是使用synchronized来实现同步锁,从而使得线程安全,但是并发度不高。所以一般使用ConcurrentHashMap来替代

Question9:为什么在1.8中当链表长度为8时转换为红黑树,数据长度为6时转化为链表?

答: 首先从时间复杂度方面来分析的话,当长度为6时查找的平均长度为6/2=3,(底层会判断偏后还是偏前,以此来从后或者从前遍历),而红黑数log6=2.6,如果为8的时候,此时8/2=4,而log8为3,至于具体这样选,是一种空间和时间的权衡。

HashMap的常见问题的更多相关文章

  1. HashMap实现原理及常见问题

    1.简介 HashMap是基于哈希表的Map接口的实现,用来存放键值对(Entry<Key,Value>),并提供可选的映射操作.使用put(Key,Value)存储对象到HashMap中 ...

  2. hashMap常见问题

    [解析hashMap的源码实现]      点击进入hashMap的源码实现 0.谈谈对hashMap的理解? 从底层结构.存取.扩容.冲突.实现原理.源码等方面说明. 1.你知道哪些常用的Map集合 ...

  3. HashMap底层实现原理及面试常见问题

    HashMap底层源码分析 1.HashMap底层采用的存储结构 1.在JDK1.7及之前采用的存储结构是数组+链表 2.到了JDK1.8之后采用的是数组+链表+红黑树 2.HashMap实现的原理 ...

  4. (转)Java集合框架:HashMap

    来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...

  5. JAVA hashmap知识整理

    HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题.HashMap的工作原理.ArrayList与Vect ...

  6. [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.

    注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...

  7. Android WebView常见问题及解决方案汇总

    Android WebView常见问题解决方案汇总: 就目前而言,如何应对版本的频繁更新呢,又如何灵活多变地展示我们的界面呢,这又涉及到了web app与native app之间孰优孰劣的争论. 于是 ...

  8. HashMap总结

    最近朋友推荐的一个很好的工作,又是面了2轮没通过,已经是好几次朋友内推没过了,觉得挺对不住朋友的.面试反馈有一方面是有些方面理解思考的还不够,平时也是项目进度比较紧,有些方面赶进度时没有理解清楚的后面 ...

  9. Maven使用常见问题整理

    Maven使用常见问题整理  1.更新eclipse的classpath加入新依赖  1.在dependencyManagement里面加入包括版本在内的依赖信息,如:   <dependenc ...

随机推荐

  1. Jenkins初体验-安装与部署服务

    一.概述 1.简介 在工作中接触到CD/CI,Devops相关的技术,本文记录Jenkins的基本使用.Jenkins是一款开源的持续集成工具,能够集成一套自动化部署任务. 目标 通过jenkins从 ...

  2. nyoj 655-光棍的yy (python, 未A)

    655-光棍的yy 内存限制:64MB 时间限制:1000ms 特判: No 通过数:4 提交数:7 难度:2 题目描述: yy经常遇见一个奇怪的事情,每当他看时间的时候总会看见11:11,这个很纠结 ...

  3. node读取excel文件生成JSON

    当前的目录结构 excel的数据如下: node识别excel,先得安装  node-xlsx,用npm或yarn都可以 npm install  node-xlsx 或 yarn add node- ...

  4. vant-ui的van-area使用

    由于官方例子中并没有太多详情,因此记录之,方便以后使用. 1.配置 :area-list="areaList",以初始化全部省市区的数据,其中area.js文件在官方可以下载,放于 ...

  5. IDEA最常用快捷键汇总+快速写出Main函数

    IDEA可以说是当下Java程序员日常开发的神器,但是想要发挥这款神器的牛逼威力,必须得熟练使用它的各种快捷键才行.本篇总结下使用IDEA(也就是IntelliJ IDEA )进行日常开发中最常用的快 ...

  6. Cygwin安装教程

    cygwin是一个在windows平台上运行的unix模拟环境,是cygnus solutions公司开发的自由软件. 它对于学习unix/linux操作环境,或者从unix到windows的应用程序 ...

  7. MySQL数据库优化技巧有哪些?

    开启查询缓存,优化查询. explain你的select查询,这可以帮你分析你的查询语句或是表结构的性能瓶颈.EXPLAIN的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序的 ...

  8. 程序员用于机器学习编程的Python 数据处理库 pandas 入门教程

    入门介绍 pandas适合于许多不同类型的数据,包括: · 具有异构类型列的表格数据,例如SQL表格或Excel数据 · 有序和无序(不一定是固定频率)时间序列数据. · 具有行列标签的任意矩阵数据( ...

  9. SpringBoot时间参数处理完整解决方案

    在JavaWeb程序的开发过程中,接口是前后端对接的主要窗口,而接口参数的接收有时候是一个令人头疼的事情,这其中最困扰程序猿的,应该是时间参数的接收. 比如:设置一个用户的过期时间,前端到底以什么格式 ...

  10. mvc 学习笔记

    1.routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); MVC中的路由忽略,只要访问的地址中带有 .axd , 该请求都将排除在mv ...