HashMap 概述

如果你没有时间细抠本文,可以直接看 HashMap 概述,能让你对 HashMap 有个大致的了解

HashMap 是 Map 接口的实现,HashMap 允许空的 key-value 键值对,HashMap 被认为是 Hashtable 的增强版,HashMap 是一个非线程安全的容器,如果想构造线程安全的 Map 考虑使用 ConcurrentHashMap。HashMap 是无序的,因为 HashMap 无法保证内部存储的键值对的有序性。

HashMap 的底层数据结构是数组 + 链表的集合体,数组在 HashMap 中又被称为桶(bucket)。遍历 HashMap 需要的时间损耗为 HashMap 实例桶的数量 + (key - value 映射) 的数量。因此,如果遍历元素很重要的话,不要把初始容量设置的太高或者负载因子设置的太低。

HashMap 实例有两个很重要的因素,初始容量和负载因子,初始容量指的就是 hash 表桶的数量,负载因子是一种衡量哈希表填充程度的标准,当哈希表中存在足够数量的 entry,以至于超过了负载因子和当前容量,这个哈希表会进行 rehash 操作,内部的数据结构重新 rebuilt。

注意 HashMap 不是线程安全的,如果多个线程同时影响了 HashMap ,并且至少一个线程修改了 HashMap 的结构,那么必须对 HashMap 进行同步操作。可以使用 Collections.synchronizedMap(new HashMap) 来创建一个线程安全的 Map。

HashMap 会导致除了迭代器本身的 remove 外,外部 remove 方法都可能会导致 fail-fast 机制,因此尽量要用迭代器自己的 remove 方法。如果在迭代器创建的过程中修改了 map 的结构,就会抛出 ConcurrentModificationException 异常。

下面就来聊一聊 HashMap 的细节问题。我们还是从面试题入手来分析 HashMap 。

HashMap 和 HashTable 的区别

我们上面介绍了一下 HashMap ,现在来介绍一下 HashTable

相同点

HashMap 和 HashTable 都是基于哈希表实现的,其内部每个元素都是 key-value 键值对,HashMap 和 HashTable 都实现了 Map、Cloneable、Serializable 接口。

不同点

  • 父类不同:HashMap 继承了 AbstractMap 类,而 HashTable 继承了 Dictionary

  • 空值不同:HashMap 允许空的 key 和 value 值,HashTable 不允许空的 key 和 value 值。HashMap 会把 Null key 当做普通的 key 对待。不允许 null key 重复。

  • 线程安全性:HashMap 不是线程安全的,如果多个外部操作同时修改 HashMap 的数据结构比如 add 或者是 delete,必须进行同步操作,仅仅对 key 或者 value 的修改不是改变数据结构的操作。可以选择构造线程安全的 Map 比如 Collections.synchronizedMap 或者是 ConcurrentHashMap。而 HashTable 本身就是线程安全的容器。

  • 性能方面:虽然 HashMap 和 HashTable 都是基于单链表的,但是 HashMap 进行 put 或者 get

    看完这篇 HashMap,和面试官扯皮就没问题了的更多相关文章

    1. 看完这篇HTTP,跟面试官扯皮就没问题了

      我是一名程序员,我的主要编程语言是 Java,我更是一名 Web 开发人员,所以我必须要了解 HTTP,所以本篇文章就来带你从 HTTP 入门到进阶,看完让你有一种恍然大悟.醍醐灌顶的感觉. 最初在有 ...

    2. 看完这篇Exception 和 Error,和面试官扯皮就没问题了

      在 Java 中的基本理念是 结构不佳的代码不能运行,发现错误的理想时期是在编译期间,因为你不用运行程序,只是凭借着对 Java 基本理念的理解就能发现问题.但是编译期并不能找出所有的问题,有一些 N ...

    3. 【Java8新特性】Stream API有哪些中间操作?看完你也可以吊打面试官!!

      写在前面 在上一篇<[Java8新特性]面试官问我:Java8中创建Stream流有哪几种方式?>中,一名读者去面试被面试官暴虐!归根结底,那哥儿们还是对Java8的新特性不是很了解呀!那 ...

    4. 看完这篇 HTTPS,和面试官扯皮就没问题了

      下面我们来一起学习一下 HTTPS ,首先问你一个问题,为什么有了 HTTP 之后,还需要有 HTTPS ?我突然有个想法,为什么我们面试的时候需要回答标准答案呢?为什么我们不说出我们自己的想法和见解 ...

    5. 看完这篇 Session、Cookie、Token,和面试官扯皮就没问题了

      Cookie 和 Session HTTP 协议是一种无状态协议,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录:Session 和 Cookie 的主要目的 ...

    6. 看完这篇 final、finally 和 finalize 和面试官扯皮就没问题了

      我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star https://github.com/crisxuan/bestJavaer 已提交此篇文章 final 是 Java 中的关键字 ...

    7. 原来ReadWriteLock也能开发高性能缓存,看完我也能和面试官好好聊聊了!

      大家好,我是冰河~~ 在实际工作中,有一种非常普遍的并发场景:那就是读多写少的场景.在这种场景下,为了优化程序的性能,我们经常使用缓存来提高应用的访问性能.因为缓存非常适合使用在读多写少的场景中.而在 ...

    8. HashMap? ConcurrentHashMap? 相信看完这篇没人能难住你!

      前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇主要想讨论 ConcurrentHashMap 这样一个并发容器,在正式开始之前我觉得有必要谈谈 ...

    9. 看完这篇Redis缓存三大问题,保你面试能造火箭,工作能拧螺丝。

      前言 日常的开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题. 一旦涉及大数据量的需求,如一些商品抢购的情景,或者主页访问量瞬间较 ...

    随机推荐

    1. java1.8时间处理

      object TimeUtil { var DEFAULT_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss") var H ...

    2. vivo产能问题

      生产手机,第一天量产1台,接下来2天(即第二.三天)每天量产2件,接下来3天(即第四.五.六天)每天量产3件 ... ... 以此类推,请编程计算出第n天总共可以量产的手机数量. public int ...

    3. 【JVM】如何理解强引用、软引用、弱引用、虚引用?

      整体架构 强引用 强引用是默认支持,当内存不足的时候,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会回收对象. 强引用是最常见的普通对象引用,只要还有强引用指向对象,对象就存活,垃圾回 ...

    4. cmd启动mysql,服务名无效

      通过cmd无法启动mysql 解决办法: 在计算机管理(或者win+R,输入services.msc)中打开服务,查看mysql服务的名称是否正确. 键入正确的名称启动mysql.

    5. Java实现 LeetCode 726 原子的数量(递归+HashMap处理)

      726. 原子的数量 给定一个化学式formula(作为字符串),返回每种原子的数量. 原子总是以一个大写字母开始,接着跟随0个或任意个小写字母,表示原子的名字. 如果数量大于 1,原子后会跟着数字表 ...

    6. Java实现 蓝桥杯 算法训练 数字三角形

      算法训练 数字三角形 时间限制:1.0s 内存限制:256.0MB 问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每 ...

    7. Java实现 蓝桥杯 算法提高 求arccos值

      算法提高 7-2求arccos值 时间限制:10.0s 内存限制:256.0MB 提交此题 问题描述 利用标准库中的cos(x)和fabs(x)函数实现arccos(x)函数,x取值范围是[-1, 1 ...

    8. Linux 用户组管理命令

      groupadd 组名,可以添加用户组 groupmod -n 新组名 老组名,可以修改组名 groupdel 组名,可以删除组(组中不能有初始用户存在,附加用户无所谓) gpasswd -a 用户名 ...

    9. 启动appium server时打印日志时间

      在调试脚本的时候想看查找元素和执行命令花了多少时间,我们可以在启动appium server的时候加上启动参数,实现我们的需求. 1)输入:appium h,可以查看appium提供的启动参数有哪些. ...

    10. 创建sudo -i免密权限账户

      项目原因,服务器需要创建普通用户,但又不能让用户拿到root密码. 创建用户 [root@bogon ~]# groupadd connect [root@bogon ~]# useradd -g c ...