HashMap、HashTable与ConcurrentHashMap的区别与联系

HashMap        

        HashMap 是基于哈希表的 Map 接口实现,它存储的内容是键值对(key-value)。HashMap 的底层实现原理涉及数组、链表和红黑树的结合使用。

HashMap的数据结构

        HashMap 的内部结构是一个数组(Node[] table),这个数组的每个元素都是一个链表的头节点。当链表的长度超过一定阈值(默认为8),并且数组的大小不小于64,链表结构会转换成红黑树结构,这样可以提高查询效率。

键值对的存储原理(put方法)

        当使用 put 方法存储键值对时,HashMap 会首先计算键(key)的 hashCode,然后通过哈希算法将这个 hashCode 转换成数组的下标,从而确定在数组中的存储位置。如果该位置没有其他元素,新的键值对就直接存储在这里。如果位置已经有元素存在,就会发生哈希冲突,新的元素会以链表的形式存储在这个位置的末尾。在 Java 8 中,如果链表的长度超过8,链表会转换成红黑树。

扩容机制

        当 HashMap 中的元素数量达到数组大小与加载因子(默认为0.75)的乘积时,数组会进行扩容,通常是扩容为原来的两倍。扩容是一个成本较高的操作,因为它涉及到重新计算每个元素的存储位置并将它们移动到新的数组中。

红黑树的引入

        为了解决链表长度过长导致的查询效率低下的问题,Java 8 引入了红黑树。红黑树是一种自平衡的二叉查找树,它保证了最坏情况下的时间复杂度为 O(log n),大大优化了长链表的查询速度。

重要考虑

  • 线程安全:HashMap 不是线程安全的,如果需要在多线程环境中使用,可以考虑使用 ConcurrentHashMap

  • 键的不变性:作为键的对象最好是不可变的,或者至少保证在作为 HashMap 键的生命周期内不会改变,因为这会影响 hashCode 的计算和键值对的位置。

  • 负载因子和初始容量:合理的设置负载因子和初始容量可以减少扩容操作,提高 HashMap 的性能。

HashTable

数据结构

        HashTable底层也是使用数组+链表的数据结构来存储数据。但与HashMap不同的是,HashTable中的数组每个元素的初始状态就是一个链表,而HashMap是当发生哈希冲突时才使用链表。

线程安全性

        与HashMap不同,HashTable是线程安全的。这是因为HashTable的主要方法,如put、get、remove等,都有synchronized修饰,确保在多线程环境下,只有一个线程能操作HashTable,从而保证线程安全。

不允许null键和null值

        HashTable不允许使用null作为键或值,如果尝试将null作为键或值放入HashTable,会抛出NullPointerException。而HashMap则允许使用null作为键或值。

性能

        因为HashTable的所有主要方法都加了synchronized关键字,所以在单线程环境下,HashTable的性能会比HashMap差一些。而在多线程环境下,由于HashTable的线程安全特性,其性能可能会优于HashMap。

扩容机制

        当HashTable中的元素数量达到一定的阈值时,也会触发扩容。扩容后的HashTable大小会是原大小的两倍,并且所有的元素都需要被重新哈希,放入新的数组位置。

ConcurrentHashMap

ConcurrentHashMap是线程安全的数组,是HashTable的替代品,同为线程安全,其性能要比HashTable更好

分段锁机制将数据分成多个 segment 来实现锁的粒度更细,从而减小锁的竞争范围,提高并发性能。

CAS 乐观锁算法(Compare and Swap)CAS操作包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。如果内存位置V的值与预期原值A相匹配,那么将内存位置V的值更新为新值B,返回true;如果不匹配,则不做任何操作并返回false。整个过程是原子的。

扩容机制默认的加载因子是0.75,意味着当表填满到3/4时,扩容2倍,默认为16过程将开始。扩容时,会创建一个新的、容量更大的哈希表,新容量通常是旧容量的两倍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1551025.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【电力系统】电力系统状态估计

摘要 电力系统状态估计是确保电力系统安全稳定运行的重要技术之一。本文利用Matlab实现了一种基于加权最小二乘法(WLS)的状态估计算法,能够在不同测量条件下准确估计电力系统的状态变量。通过对典型电力系统的仿真分析,验证了算法…

第三节-类与对象(2)默认成员函数详解

1.类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类(空类大小为1)。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:…

第L2周:机器学习|线性回归模型 LinearRegression:2. 多元线性回归模型

本文为365天深度学习训练营 中的学习记录博客原作者:K同学啊 任务: ●1. 学习本文的多元线形回归模型。 ●2. 参考文本预测花瓣宽度的方法,选用其他三个变量来预测花瓣长度。 一、多元线性回归 简单线性回归:影响 Y 的因素唯一&…

依赖倒置原则(学习笔记)

抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。 依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。 以…

vue + echarts 快速入门

vue echarts 快速入门 本案例即有nodejs和vue的基础,又在vue的基础上整合了echarts Nodejs基础 1、Node简介 1.1、为什么学习Nodejs(了解) 轻量级、高性能、可伸缩web服务器前后端JavaScript同构开发简洁高效的前端工程化 1.2、Nodejs能做什么(了解) Node 打破了…

Android 安卓内存安全漏洞数量大幅下降的原因

谷歌决定使用内存安全的编程语言 Rust 向 Android 代码库中写入新代码,尽管旧代码(用 C/C 编写)没有被重写,但内存安全漏洞却大幅减少。 Android 代码库中每年发现的内存安全漏洞数量(来源:谷歌&#xff09…

常用的cmd命令——使用bat命令创建程序的快捷方式

示例使用场景:例如便携版的软件,需要往桌面发快捷方式 如便携的浏览器,给桌面发送快捷方式,同时设置快捷方式的启动参数。 下面以谷歌浏览器为例: 浏览器的App的下级目录为如下内容 知道了所需文件的位置,…

废品回收小程序/环保垃圾回收/收二手垃圾小程序/分类资源回收系统/独立版系统源码

>>>系统简述: 1.以微信小程序为基础进行开发,体验好,操作方便 2.从用户下单到回收员接单,在到回收站接收,在到代理全流程通过手机端管理 3.支持废品分类下单,并支持分类数据统计 4.独创回收员多个…

五金精密加工提升效率的方法与技巧

在五金精密加工领域,提高加工效率是企业增强竞争力的关键。以下是一些有效的提升方法与技巧。 一、优化加工设备 设备升级与更新 定期评估加工设备的性能,引进先进的五金精密加工机床。例如,高精度的数控加工中心能够实现多轴联动加工&#x…

Android15车载音频之CarAudioService加载解析各音区参数过程(八十七)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+…

【sourceTree问题】拉取提交的时候需要频繁输入账号密码

用sourceTree进行代码管理的时候会出现一直让输入账号密码的问题,烦不胜烦,可以点击【设置】 → 【编辑配置文件...】打开配置文件: 在配置文件里找到url,把url里面的网址修改为: http://username:passwordxxxxx/xx…

Qt——如何创建一个项目

前言 本文主要通过实操带领大家来实现基础文件的操作,主要包括文件的打开,读取,写入,当然文件读写我们可以有几种不同的方式来进行操作,分别是文件流,字节流来进行的操作这里就需要两个类分别是文件流&…

速通数据结构与算法第六站 树堆

系列文章目录 速通数据结构与算法系列 1 速通数据结构与算法第一站 复杂度 http://t.csdnimg.cn/sxEGF 2 速通数据结构与算法第二站 顺序表 http://t.csdnimg.cn/WVyDb 3 速通数据结构与算法第三站 单链表 http://t.csdnimg.cn/cDpcC 4 速通…

学习记录:js算法(四十四):二叉树的最大深度

文章目录 二叉树的最大深度我的思路网上思路 总结 二叉树的最大深度 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 图一: 示例 1:(如图一) 输入:root [3,9,20,…

Javase学习day1-前置知识

1、什么是计算机 2、 硬件及冯诺依曼结构 3、软件及软件开发 4、常用的快捷键 5、常用的Dos命令 常用的Dos命令:(基本都是在cmd里面写的) #盘符切换:直接输入那个盘符的名字加一个冒号就行。 #切换目录: cd change directory(这是…

第十七章:c语言内存函数

1. memcpy使⽤和模拟实现 2. memmove使⽤ 3. memset函数的使⽤ 4. memcmp函数的使⽤ 天行健 君子以自强不息一、memcpy的使用和模拟实现 作用: 1. 函数memcpy从source的位置向后复制num个字节的数据到destination指向的内存位置。 2. 这个函数在遇到‘\0’的时…

用Python实现运筹学——Day 7: 线性规划的对偶理论

一、学习内容 1. 对偶问题的概念与对偶定理 线性规划的对偶理论是一种非常重要的理论,能揭示线性规划问题中的原问题和对偶问题之间的关系。给定一个线性规划的原问题,可以通过构造一个相关的对偶问题来帮助理解原问题的解,或者直接求解对偶…

详细分析Java中的StopWatch基本知识(附Demo)

目录 前言1. 基本知识2. Demo 前言 对于Java的基本知识推荐阅读: java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)【Java项目】实战CRUD的功能整理(持续更新) 1. 基本知识 StopWatch 是 Spring Fra…

【TabBar嵌套Navigation案例-新特性页面-背景图片 Objective-C语言】

一、接下来,我们来做这个背景图片的这个功能啊 1.首先呢,我们command + R跑一下,现在都是有一堆颜色, 大体的这个框架啊,我们都已经搭好了, 接下来,我们把这几个颜色啊,CollectionView的背景图片,给它设置一下, 首先呢,这个设置啊,我们这么着来做,我们呢,肯定…

解决:使用layui.treeTable.updateNode,更新表格数据后,done里面的事件丢失问题

1. 背景 在给树形表格添加行点击事件,并且只更新当前行数据。 treeTable.updateNode("SpeProjListId", result.LAY_DATA_INDEX, result);更新数据后,点击事件失效。 1. 给字段绑定事件: class"link_a link_style" , {…