【Java】HashMap、HashTable和ConcurrentHashMap的区别

在这里插入图片描述

文章目录

  • 区别
  • 一、HashMap
    • 1.1基本定义与特性
    • 1.2工作原理与实现
    • 1.3常用方法
    • 1.4性能与优化
  • 二、HashTable
  • 三、ConcurrentHashMap
    • 3.1基本特点
    • 3.2实现原理
    • 3.3常用方法
    • 3.4适用场景
    • 3.5性能优化

HashTable、HashMap和ConcurrentHashMap之间的区别主要体现在线程安全、继承关系与实现接口、对null值的处理、性能以及数据结构等几个方面。以下是对这三者之间区别的详细分析:

区别

项目HashMapHashTableConcurrentHashMap
null键允许(仅能有一个)不允许允许(仅能有一个)
null值允许不允许允许
性能高(单线程下最高)多线程下优于HashTable
数据结构数组+链表+红黑树数组+链表数组+链表+红黑树
继承关系AbstractMap类Dictionary类AbstractMap类
实现接口实现了Map接口Cloneable接口和Serializable接口实现了Map接口实现了Map接口、Cloneable接口和Serializable接口
线程安全不安全安全安全
同步方式synchronized同步方法1.7版本:基于segment分段锁机制,基于ReentrantLock实现;1.8版本:基于CAS+synchronized实现,空节点插入使用CAS,有Node节点则使用synchronized加锁

一、HashMap

HashMap是Java中的一种基于哈希表实现的数据结构,它实现了Map接口并允许使用null键和null值。

1.1基本定义与特性

基于哈希表: HashMap是基于哈希表实现的,通过哈希函数将键映射到索引位置,实现快速查找。
允许null键和值: 与HashTable不同,HashMap允许使用null作为键和值。
非线程安全: HashMap不是线程安全的,因此在多线程环境下使用时需要注意数据一致性问题。

1.2工作原理与实现

哈希函数: HashMap使用哈希函数将键转换为索引,该函数需要满足确定性、高效性和散列性。
冲突解决: 采用链地址法处理哈希冲突,即多个键哈希到同一个索引时,它们会被链接到一个链表中。
动态扩容: 当元素数量超过当前容量的阈值时,HashMap会进行rehashing,创建一个新的数组,并将原数组中的元素重新哈希到新的数组中。

1.3常用方法

put(K key, V value): 向HashMap中添加一个键值对。
get(Object key): 根据键获取对应的值。
remove(Object key): 删除HashMap中指定的键值对。
size(): 返回HashMap中键值对的数量。
isEmpty(): 判断HashMap是否为空。
keySet(): 返回HashMap中所有键的集合。
values(): 返回HashMap中所有值的集合。
entrySet(): 返回HashMap中所有键值对组成的集合。

1.4性能与优化

时间复杂度: HashMap的查找、插入和删除操作的平均时间复杂度为O(1),但在哈希冲突严重时,性能会下降。
链接: 【哈希表】为什么哈希表的插入/删除/查找时间复杂度为O(1)

初始容量与加载因子: 合理设置HashMap的初始容量和加载因子可以提高性能。初始容量是HashMap创建时分配的数组大小,加载因子是触发扩容的阈值。
红黑树优化: 在JDK 1.8及以后的版本中,当链表长度超过一定阈值时,HashMap会将链表转换为红黑树以提高查找性能。

总之,HashMap是一种高效且灵活的数据结构,适用于需要快速查找键值对的场景。在使用时需要注意其非线程安全的特性,并在必要时采取适当的同步措施。

二、HashTable

HashTable(哈希表)是一种根据关键码值直接进行访问的数据结构。它通过特定的哈希函数将关键码值映射到表中的一个位置,以加快数据查找的速度。

  1. HashTable同样是基于哈希表实现,存储的数据同样为key-value键值对,其内部也是通过单链表解决哈希冲突的,容量不足时,同样会自动扩容;

  2. 线程安全,可以用于多线程场景。它的线程安全实现方式是:所有的方法都使用synchronized加锁,像一些读操作不存在线程不安全问题,所以全部方法加锁导致了效率低下。

  3. 现在已经被丢了不再使用了。不涉及线程安全问题时使用HashMap,要保证线程安全时,使用ConcurrentHashMap。

三、ConcurrentHashMap

ConcurrentHashMap是Java集合框架中的一个类,它是HashMap的一个线程安全版本,专为高并发场景设计

3.1基本特点

线程安全: ConcurrentHashMap通过特殊的锁机制和数据结构来确保线程安全,使得多个线程可以并发地读写不同的数据段,而不需要额外的同步措施。

高并发性能: 由于采用了分段锁机制(在Java 8之前)或更精细的锁策略(如CAS和synchronized在Java 8及之后),ConcurrentHashMap能够支持多个线程同时访问不同的数据段,从而提高了并发性能。

支持高效的读操作: 在没有竞争的情况下,读操作几乎没有性能损耗,因为它们可以并行执行。

不允许null键或值: 与HashMap不同,ConcurrentHashMap不允许键或值为null。

3.2实现原理

分段锁机制(Java 7及之前): ConcurrentHashMap在内部将数据分为多个段(Segment),每个段都有自己的锁。当一个线程访问某个段时,它只会锁定该段,而不会锁定整个ConcurrentHashMap。这使得多个线程可以同时访问不同的段,从而提高了并发性能。

更精细的锁策略(Java 8及之后): 在Java 8中,ConcurrentHashMap的实现进行了改进,不再使用分段锁,而是采用了CAS操作和synchronized关键字来实现更精细的锁控制,进一步提高了并发性能。

3.3常用方法

ConcurrentHashMap提供了一系列与HashMap相似的方法,如put、get、remove等,这些方法都是线程安全的。
此外,它还提供了一些原子操作,如putIfAbsent、remove、replace等。

3.4适用场景

ConcurrentHashMap适用于需要在线程安全的环境下使用HashMap的场景,特别是需要实现高并发下的数据访问控制的场景
例如,在多线程环境中记录日志信息时,可以使用ConcurrentHashMap来存储日志数据,以确保数据的一致性和安全性。

3.5性能优化

Java 8对ConcurrentHashMap进行了一些性能优化,包括利用CAS操作替换了之前的Synchronized关键字来减少锁的争用等。这些优化进一步提高了ConcurrentHashMap的并发性能。


以上就是本文所有内容,如果对你有帮助的话,点赞收藏支持一下吧!💞💞💞

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql 和 PostgreSQL 到底选啥?

当我深入探讨MySQL和PostgreSQL这两个著名的开源数据库时,我们不仅发现它们在功能、性能和用例方面存在明显的差异,同时也能看出它们各自在特定场景下的独特优势。选择哪一个往往取决于项目的具体需求、团队的熟悉度以及未来的扩展计划。 在这篇文章中&…

kaggle 泰坦尼克号2 得分0.7799

流程 导入所要使用的包引入kaggle的数据集csv文件查看数据集有无空值填充这些空值提取特征分离训练集和测试集调用模型 导入需要的包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import warnings warnings.filterwarni…

Vue3: 获取元素DOM的方法

Vue3中获取dom的方法有两种 : ref模板引用和传统方法 1.ref模板引用 模板引用是官方提出的方法&#xff0c;请看下面的例子&#xff1a; <template><canvas ref"solarCanvas" id"solar" width"1300" height"900"></…

K8S 污点和容忍度(Taint,Toleration)

介绍 在 Kubernetes 中&#xff0c;污点&#xff08;Taints&#xff09;和容忍度&#xff08;Tolerations&#xff09;是用于节点调度的一种机制&#xff0c;它们允许你控制哪些 Pod 能够调度到哪些节点上。 污点&#xff08;Taints&#xff09; 污点是节点上的一种属性&…

从C到JAVA之学习JAVA的第一周笔记

文章目录 java语言概述JDK与JRE编写执行过程第一份java代码解读编写编译运行其他 注释三种注释方法 java API文档关键字标识符数据类型基本数据类型自动类型提升规则引用数据类型 string概述String与基本数据类型的变量间的运算 运算符键盘录入运行控制语句数组定义与静态初始化…

springboot no mapping for.....解决办法

这个问题是由于没有加入对应的GET,POST注解&#xff0c;导致映射失败&#xff0c;加入对应注解就ok了

JDK 11下载、安装、配置

下载 到Oracle管网下载JDK 11&#xff0c;下载前需要登录&#xff0c;否则直接点下载会出现502 bad gateway。 下载页面链接 https://www.oracle.com/hk/java/technologies/downloads/#java11-windows 登录 有些人可能没有Oracle账号&#xff0c;注册也比较慢&#xff0c;有需…

随笔05 我的创作纪念日(512天)

机缘 机缘这事儿&#xff0c;我在随笔系列博文里已经翻来覆去说了不少&#xff0c;这次就不再唠叨了&#xff0c;省得被小伙伴嫌弃成祥林嫂~&#x1f61c; &#x1f338;随笔01 我的创作纪念日&#xff08;128天&#xff09;_newmitbbs-CSDN博客 收获 我这一小片自留地&…

os模块学习

【一】文件路径相关的操作 【1】获取当前文件所在的文件夹路径 # os.path.dirname(__file__) ​ import os file_name os.path.dirname(__file__) print(file_name) # H:\pycharm projects\day\模块学习2 【2】获取当前文件所在的文件路径 # os.path.abspath(__fil…

echarts部分属性使用

标题部分 (title): 控制图表的标题显示&#xff0c;包括主标题和副标题。你可以设置标题的文字内容、样式、位置等属性。 图例部分 (legend): 图例是用来标识每个系列的名称的&#xff0c;可以让用户通过点击图例来控制显示/隐藏对应的数据系列。 提示框部分 (tooltip): 当鼠…

Rust基本数据类型-字符串

一、字符串是什么&#xff0c;怎么用 1、字符串是什么 先说明一下&#xff0c;在Rust中&#xff0c;字符是UniCode编码占4个字节&#xff0c;字符串类型的字符是UTF-8编码的&#xff0c;字节大小为1&#xff5e;3。 字符串类型在Rust中&#xff0c;可以分为&Str和String…

【极速前进】20240415-20240421:TR-DPO、压缩与智能的线性关系、模拟伪代码改善算术能力、Many-shot、合成数据综述

一、TR-DPO&#xff1a;更新reference模型能实现更好的对齐 论文地址&#xff1a;https://arxiv.org/pdf/2404.09656.pdf ​ 语言模型对齐的训练目标是&#xff1a; max ⁡ π θ E x ∼ D , y ∼ π θ ( y ∣ x ) [ r ϕ ( x , y ) ] − β D KL [ π θ ( x , y ) ∥ π …

JavaEE 初阶篇-深入了解 File 文件操作(实现文件搜索、非空文件夹删除)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 File 文件概述 2.0 创建 File 类对象的方法 2.1 判断文件类型、获取文件信息的方法 2.2 创建文件、删除文件的方法 2.3 遍历文件夹的方法 3.0 文件搜索与删除 3.1…

OSPF面试题收集

第一章:基础理论部分 基础部分面试官主要是问一些简单得原理,口头描述的东西。不会涉及到报文的参数属性等。 OSPF是什么 定义也就是链路状态协议和距离矢量协议的区别区别。 开放式最短路径优先协议 路由是以自己为根,根据数据库计算去往所有树枝节点的最佳路径放进自己…

WebSocket 快速入门 - springboo聊天功能

目录 一、概述 1、HTTP&#xff08;超文本传输协议&#xff09; 2、轮询和长轮询 3、WebSocket 二、WebSocket快速使用 1、基于Java注解实现WebSocket服务器端 2、JS前端测试 三、WebSocket进阶使用 1、如何获取当前用户信息 2、 后端聊天功能实现 一、概述 HTTP…

PVE grub resue错误修复 lvmid BUG

服务器断电后启动不起来&#xff0c;显示grub resue 找了半天没有找到修复方法。看官方文档有一处Recovering from grub “disk not found” error when booting from LVM 极为类似。https://pve.proxmox.com/wiki/Recover_From_Grub_Failure 下面是处理过程。 使用PVE 6.4启…

Leetcode算法训练日记 | day33

专题九 贪心算法 一、跳跃游戏 1.题目 Leetcode&#xff1a;第 55 题 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 …

机器学习(二)之监督学习

前言&#xff1a; 上一节大概讲解了几种学习方式&#xff0c;下面几张就具体来讲讲监督学习的几种算法。 以下示例中和都是权重的意思&#xff01;&#xff01;&#xff01; 注&#xff1a;本文如有错误之处&#xff0c;还请读者指出&#xff0c;欢迎评论区探讨&#xff01; 1…

MATLAB实现图片栅格化

MATLAB实现图片栅格化 1.读取图片&#xff1a;首先&#xff0c;你需要使用imread函数读取要栅格化的图片。 2.设置栅格大小&#xff1a;确定你希望将图片划分成的栅格大小&#xff0c;即每个栅格的宽度和高度。 3.计算栅格数量&#xff1a;根据图片的总尺寸和栅格大小&#…

搜索+剪枝,LeetCode 216. 组合总和 III

目录 一、题目 1、题目描述 2、接口描述 python3 cpp 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 python3 cpp 一、题目 1、题目描述 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多…