一篇文章带你彻底理解Java HashMap数据结构详解

news2024/11/27 10:20:06

基本概念:

​ HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。

HashMap 是无序的,即不会记录插入的顺序。

HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。

img

HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。

PS:如果需要在多线程环境中使用 HashMap,并保证线程安全,可以使用 java.util.concurrent.ConcurrentHashMap。ConcurrentHashMap 是 Java 提供的一个线程安全的哈希表实现,它可以替代 HashMap 在并发环境中的使用。


HashMap 的 key 与 value 类型可以相同也可以不同,可以是字符串(String)类型的 key 和 value,也可以是整型(Integer)的 key 和字符串(String)类型的 value。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k7axV6X4-1691391012852)(https://static.runoob.com/images/mix/java-map.svg)]

HashMap 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类。

基本类型对应的包装类表如下:

基本类型引用类型
booleanBoolean
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter

HashMap 类位于 java.util 包中,使用前需要引入它,语法格式如下:

import java.util.HashMap; // 引入 HashMap 类

以下实例我们创建一个 HashMap 对象 FritsSites, 整型(Integer)的 key 和字符串(String)类型的 value:

HashMap<Integer, String> FruitsSites = new HashMap<Integer, String>();

小结一下HashMap 的基本概念如下:

  1. 键(Key):每个键必须是唯一的。键用于查找和访问与之关联的值。在 HashMap 中,键可以是任意对象,但通常使用不可变(immutable)的对象作为键,例如字符串、数字等。
  2. 值(Value):与每个键关联的值。值可以是任意对象,包括 null。
  3. 哈希表(Hash Table):HashMap 内部使用哈希表数据结构来存储键值对。哈希表通过将键映射为数组索引来实现高效的检索操作。
  4. 哈希码(Hash Code):每个键都有一个对应的哈希码,用于确定键在哈希表中的位置。hashCode() 方法用于计算键的哈希码。
  5. 冲突(Collision):当不同的键具有相同的哈希码时,称为冲突。HashMap 使用链表或红黑树来解决冲突,以确保键值对能正确存储和检索。

HashMap的特点如下:

  • 高效的插入、删除和查找操作:由于使用了哈希表,HashMap 提供了接近常数时间复杂度的性能。
  • 无序的键值对:HashMap 不保证键值对的顺序,因为它是基于哈希表实现的。
  • 允许 null 键和 null 值:HashMap 中可以存储 null 键和 null 值。
  • 非线程安全:HashMap 不是线程安全的,如果多个线程同时访问同一个 HashMap 并进行修改,可能会导致不确定的结果。如果需要在多线程环境中使用,可以考虑使用 ConcurrentHashMap。

下面是具体的例子:

import java.util.HashMap;
import java.util.Map;

public class HashMapExample {
    public static void main(String[] args) {
        Map<String, Integer> fruitQuantityMap = new HashMap<>();

        // 添加键值对
        fruitQuantityMap.put("Apple", 10);
        fruitQuantityMap.put("Banana", 5);
        fruitQuantityMap.put("Orange", 8);

        System.out.println("HashMap 初始内容: " + fruitQuantityMap);

        // 修改键为 "Banana" 的值为 6
        fruitQuantityMap.put("Banana", 6);
        System.out.println("修改后的 HashMap: " + fruitQuantityMap);

        // 删除键为 "Orange" 的键值对
        fruitQuantityMap.remove("Orange");
        System.out.println("删除键为 \"Orange\" 后的 HashMap: " + fruitQuantityMap);

        // 获取键为 "Apple" 的值
        int appleValue = fruitQuantityMap.get("Apple");
        System.out.println("键为 \"Apple\" 的值为: " + appleValue);

        // 遍历 HashMap
        System.out.println("遍历 HashMap:");
        for (Map.Entry<String, Integer> entry : fruitQuantityMap.entrySet()) {
            String fruit = entry.getKey();
            int quantity = entry.getValue();
            System.out.println(fruit + ": " + quantity);
        }
    }
}

输出结果如下:

Copy CodeHashMap 初始内容: {Apple=10, Orange=8, Banana=5}
修改后的 HashMap: {Apple=10, Orange=8, Banana=6}
删除键为 "Orange" 后的 HashMap: {Apple=10, Banana=6}
键为 "Apple" 的值为: 10
遍历 HashMap:
Apple: 10
Banana: 6

运行程序后,会输出初始的 fruitQuantityMap 的内容,然后按顺序进行修改、删除和获取操作,并显示相应的结果。最后,通过遍历 fruitQuantityMap,打印出所有水果及其对应的数量。


HashMap常用的方法有:

常用方法列表如下:

方法描述
clear()删除 hashMap 中的所有键/值对
clone()复制一份 hashMap
isEmpty()判断 hashMap 是否为空
size()计算 hashMap 中键/值对的数量
put()将键/值对添加到 hashMap 中
putAll()将所有键/值对添加到 hashMap 中
putIfAbsent()如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。
remove()删除 hashMap 中指定键 key 的映射关系
containsKey()检查 hashMap 中是否存在指定的 key 对应的映射关系。
containsValue()检查 hashMap 中是否存在指定的 value 对应的映射关系。
replace()替换 hashMap 中是指定的 key 对应的 value。
replaceAll()将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。
get()获取指定 key 对应对 value
getOrDefault()获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
forEach()对 hashMap 中的每个映射执行指定的操作。
entrySet()返回 hashMap 中所有映射项的集合集合视图。
keySet()返回 hashMap 中所有 key 组成的集合视图。
values()返回 hashMap 中存在的所有 value 值。
merge()添加键值对到 hashMap 中
compute()对 hashMap 中指定 key 的值进行重新计算
computeIfAbsent()对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中
computeIfPresent()对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。

更多 API 方法可以查看:https://www.runoob.com/manual/jdk11api/java.base/java/util/HashMap.html

结尾语:记录于2023年8月7号14时48分,以上仅为个人在[Java数据结构HashMap—Java高级编程—菜鸟教程](Java HashMap | 菜鸟教程 (runoob.com))的学习过程中遇到的问题,还有记录的个人想法,有错误欢迎指出,希望对您有帮助,感谢观看!如果可以的话,点点赞,点点关注

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

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

相关文章

嵌入式:C高级 Day4

一、整理思维导图 二、写一个函数&#xff0c;获取用户的uid和gid并使用变量接收 三、整理冒泡排序、简单选择排序和快速排序的代码 冒泡排序 #include <myhead.h>void output(int arr[], int len); void bubble_sort(int arr[], int len);int main(int argc, const ch…

Python(Web时代)——请求钩子

简介 有时在处理请求之前或之后需要执行一部分代码&#xff0c;比如&#xff1a;创建数据库链接或进行登陆权限认证等&#xff0c;在请求结束时指定数据的交互格式等。 为了避免在每个视图函数中编写重复的代码&#xff0c;flask提供了注册通用函数的功能&#xff08;请求钩子…

【PCB专题】Allegro高速电路Xnet网络等长约束——SDIO信号为例

高速PCB板布线过程中,经常遇到等长设置问题,例如DDR的一组数据线和地址线等。但是由于数据线和地址线中间有一个电阻(或排阻),这种情况下设置等长就要引入Xnet的概念,通过设置Xnet的等长来确保数据线和地址线的等长。 由无源、分立器件(电阻、电容、电感)连接起来的几段…

新一代开源流数据湖平台Apache Paimon入门实操-下

文章目录 实战写表插入和覆盖数据更新数据删除数据Merge Into 查询表批量查询时间旅行批量增量查询 流式查询时间旅行ConsumerID 查询优化 系统表表指定系统表分区表全局系统表维表 CDC集成MySQLKafka支持schema变更 实战 写表 插入和覆盖数据 可以使用INSERT语句向表中插入…

python与深度学习(十六):CNN和宝可梦模型二

目录 1. 说明2. 宝可梦模型的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 数据处理和归一化2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章宝可梦模型训练的模型…

yolo txt 转 labelme json 格式

talk is cheap show me the code! def convert_txt_to_labelme_json(txt_path, image_path, output_dir, image_fmt.jpg):# txt 转labelme json# 将yolo的txt转labelme jsontxts glob.glob(os.path.join(txt_path, "*.txt"))for txt in txts:labelme_json {versio…

【项目 计网3】Socket介绍 4.9字节序 4.10字节序转换函数

文章目录 4.8 Socket介绍4.9字节序简介字节序举例 4.10字节序转换函数 4.8 Socket介绍 所谓 socket&#xff08;套接字&#xff09;&#xff0c;就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端&#xff0c;提供了应用层进…

培训报名小程序报名功能开发

目录 1 创建页面2 新建URL参数3 课程详细信息4 报名数据源创建5 报名信息功能开发6 设置页面跳转7 最终实现的效果总结 在培训报名小程序中&#xff0c;我们已经开发了首页和列表页。在列表页点击报名时就跳转到报名页面&#xff0c;先看我们的原型 报名页分为两个部分&#x…

反弹shell的N种姿势

预备知识1. 关于反弹shell 就是控制端监听在某TCP/UDP端口&#xff0c;被控端发起请求到该端口&#xff0c;并将其命令行的输入输出转到控制端。reverse shell与telnet&#xff0c;ssh等标准shell对应&#xff0c;本质上是网络概念的客户端与服务端的角色反转。2. 反弹shel…

【Linux命令详解 | cp命令】Linux系统中用于复制文件或目录的命令

文章标题 简介参数列表二&#xff0c;使用介绍1. 复制单个文件2. 复制多个文件3. 复制目录4. 保留文件属性5. 创建链接6. 强制覆盖7. 显示复制进度8. 创建备份9. 只有当源文件比目标文件新时才复制10. 复制链接文件 总结 简介 cp命令在Linux系统中用于复制文件或目录。其功能强…

刷题笔记 day9

1658 将 x 减到 0 的最小操作数 解析&#xff1a;1. 当数组的两端的数都大于x时&#xff0c;直接返回 -1。 2. 当数组所有数之和小于 x 时 &#xff0c;直接返回 -1。 3. 数组中可以将 x 消除为0&#xff0c;那么可以从左边减小为 0 &#xff1b;可以从右边减小为 0 &#xff1…

20230807通过ffmpeg将DTS编码的AUDIO音频转换为AAC编码

20230807通过ffmpeg将DTS编码的AUDIO音频转换为AAC编码 2023/8/7 20:04 ffmpeg dts 转AAC 缘起&#xff1a;由于网上找的电影没有中文字幕&#xff0c;有内置的英文字幕&#xff0c;但是还是通过剪映/RP2023识别一份英文字幕备用&#xff01; I:\Downloads\2005[红眼航班]Red E…

助力企业数字化转型,为何 PaaS 化是最佳方式?

在数字化的浪潮中&#xff0c;身份管理已经成为各个行业数字化转型的关键要素。建立一个高效的身份治理中台&#xff0c;不仅能有效保障企业信息安全和数据安全&#xff0c;还能提升企业的数字化程度。 然而&#xff0c;身份管理的构建并非一项简单的任务。当企业在构建身份治理…

llama2模型下载

介绍 LLaMA 2-CHAT与OpenAI ChatGPT效果一样好。LLaMA 2与LLaMA 1架构相同,LLaMA 2训练数据是2000000000000个tokens,还是用了1000000个人类新标注的数据。上下文长度由2048提升为4096。 本教程提供两种下载方式: 1官方下载脚本下载 2hugging face网站下载 官网资格申请 …

赴日IT培训 赴日程序员工作适合什么人?

日本作为全球第三大经济体&#xff0c;IT行业发展十分迅速&#xff0c;日本拥有世界领先的科技公司&#xff0c;如索尼、丰田、日立等&#xff0c;这为IT行业提供了广阔的发展平台和良好的职业前景。此外&#xff0c;日本政府对IT行业也给予了充分的政策支持&#xff0c;像是对…

[CKA]考试之查看Pod日志

由于最新的CKA考试改版&#xff0c;不允许存储书签&#xff0c;本博客致力怎么一步步从官网把答案找到&#xff0c;如何修改把题做对&#xff0c;下面开始我们的 CKA之旅 题目为&#xff1a; Task 监控名为foobar的Pod的日志&#xff0c;并过滤出具有unable-to-access-websi…

Windows系统下添加了新环境变量无需重启电脑激活新环境变量的方法

首先WinR&#xff0c;再输入cmd&#xff0c;进入终端&#xff0c;输入以下命令&#xff1a; set Pathc输入完以上命令回车&#xff0c;如下&#xff1a; 关闭终端后再次打开输入cl&#xff0c;如果输出以下类似信息说明新的环境变量已经添加成功&#xff0c;如下&#xff1a; …

前端实习day20

今天解决了不少bug&#xff0c;成就感满满&#xff0c;有几个问题困扰了我很久&#xff0c;我查阅了很多博客&#xff0c;终于找到解决思路&#xff0c;顺利解决&#xff0c;这里记录一下解决思路。 1、在通过this.$refs.layoutSide.style设置<a-layout-sider>的宽度时&…

kali常见字典目录

kali常见字典目录 Kali Linux 是一个流行的渗透测试和安全评估操作系统&#xff0c;它预装了许多用于渗透测试和安全研究的工具&#xff0c;包括各种字典文件。以下是一些 Kali Linux 中常见的字典目录&#xff1a; 当然可以&#xff01;以下是 Kali Linux 中常见的一些字典目…

小研究 - MySQL 分区分表的设计及实(二)

随着信息技术的快速发展&#xff0c;数据量越来越大&#xff0c;海量的表查询操作需要消耗大量的时间&#xff0c;成为影响数据库访问性能提高的主要因素。为了提升数据库操作的查询效率和用户体验&#xff0c;在关系型数据库管理系统(MySQL)中通过 range 分区和 Merge 存储&am…