Java手写HashMap及拓展实践

Java手写HashMap

思维导图

HashMap
数组
链表
哈希函数

上述思维导图展示了Java手写HashMap的实现思路。HashMap是一种常用的数据结构,用于存储键值对。它的底层是由数组和链表组成的。数组用于存储数据,链表用于解决哈希冲突。在HashMap中,每个键值对通过哈希函数计算出一个哈希值,然后根据哈希值找到对应的数组位置,如果该位置已经有其他键值对存在,就使用链表将新的键值对添加到该位置的链表末尾。

实现步骤

1. 定义HashMap类

首先,我们需要定义一个HashMap类,用于存储键值对。

public class HashMap<K, V> {// 实现代码
}

2. 定义数组和链表

在HashMap类中,我们需要定义一个数组和一个链表。

private Node<K, V>[] table; // 数组
private static final int DEFAULT_CAPACITY = 16; // 默认数组大小static class Node<K, V> {final K key;V value;Node<K, V> next;Node(K key, V value) {this.key = key;this.value = value;}
}

数组table用于存储键值对,链表Node用于解决哈希冲突。在链表中,每个节点包含一个键值对,以及指向下一个节点的指针。

3. 实现哈希函数

在HashMap中,我们需要实现一个哈希函数,用于计算键值对的哈希值。

private int hash(K key) {return key.hashCode() % table.length;
}

哈希函数使用hashCode()方法计算键值对的哈希值,然后使用取模运算将哈希值映射到数组的索引位置。

4. 实现put方法

接下来,我们需要实现put方法,用于向HashMap中添加键值对。

public void put(K key, V value) {int index = hash(key);Node<K, V> newNode = new Node<>(key, value);if (table[index] == null) {table[index] = newNode;} else {Node<K, V> current = table[index];while (current.next != null) {if (current.key.equals(key)) {current.value = value;return;}current = current.next;}current.next = newNode;}
}

put方法首先计算键值对的哈希值,然后根据哈希值找到对应的数组位置。如果该位置为空,则直接将新的节点添加到该位置。如果该位置已经有其他节点存在,则遍历链表,查找是否有相同的键。如果有相同的键,则更新对应的值,否则将新的节点添加到链表的末尾。

5. 实现get方法

我们还需要实现get方法,用于根据键获取对应的值。

public V get(K key) {int index = hash(key);if (table[index] == null) {return null;} else {Node<K, V> current = table[index];while (current != null) {if (current.key.equals(key)) {return current.value;}current = current.next;}return null;}
}

get方法首先计算键的哈希值,然后根据哈希值找到对应的数组位置。如果该位置为空,则返回null。如果该位置有节点存在,则遍历链表,查找是否有相同的键。如果找到相同的键,则返回对应的值,否则返回null

总结

通过手写HashMap的实现,我们加深了对HashMap的理解,并提高了编程能力。HashMap是一种常用的数据结构,它的底层是由数组和链表组成的,通过哈希函数将键值对映射到数组的索引位置,用链表解决哈希冲突。实现HashMap需要考虑哈希函数、数组和链表的操作,以及处理哈希冲突的方式。掌握HashMap的实现原理和实现步骤对于编程能力的提升是非常有帮助的。

拓展

除了基本的put和get操作,我们还可以实现其他功能,比如删除键值对、获取HashMap的大小等。删除键值对的操作比较简单,只需要找到对应的键,然后删除节点即可。获取HashMap的大小可以遍历数组,并统计每个位置的链表长度。另外,我们还可以实现自动扩容的功能,当HashMap中的键值对数量超过数组大小的75%时,自动扩容数组的大小。实现自动扩容需要创建一个新的更大的数组,并将原数组中的键值对重新计算哈希值,然后添加到新的数组中。

拓展实践

当HashMap中的键值对数量超过数组大小的75%时,我们可以通过自动扩容来提高HashMap的性能。下面是实现自动扩容的代码:

public void put(K key, V value) {int index = hash(key);Node<K, V> newNode = new Node<>(key, value);if (table[index] == null) {table[index] = newNode;} else {Node<K, V> current = table[index];while (current.next != null) {if (current.key.equals(key)) {current.value = value;return;}current = current.next;}current.next = newNode;}size++;if ((double) size / table.length > 0.75) {resize();}
}private void resize() {int newCapacity = table.length * 2;Node<K, V>[] newTable = new Node[newCapacity];for (int i = 0; i < table.length; i++) {Node<K, V> current = table[i];while (current != null) {int newIndex = current.key.hashCode() % newCapacity;Node<K, V> newNode = new Node<>(current.key, current.value);if (newTable[newIndex] == null) {newTable[newIndex] = newNode;} else {Node<K, V> newCurrent = newTable[newIndex];while (newCurrent.next != null) {newCurrent = newCurrent.next;}newCurrent.next = newNode;}current = current.next;}}table = newTable;
}

put方法中,我们首先判断当前HashMap的大小是否超过了数组大小的75%。如果是,则调用resize方法进行扩容。resize方法首先创建一个新的更大的数组newTable,然后遍历原数组table,将每个键值对重新计算哈希值,并添加到新的数组中。最后,将新的数组赋值给table

通过自动扩容,我们可以保证HashMap的性能在一定范围内。当HashMap中的键值对数量超过数组大小的75%时,我们将数组的大小扩大一倍,从而减少哈希冲突的概率,提高查找效率。

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

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

相关文章

【OJ比赛日历】快周末了,不来一场比赛吗? #09.16-09.22 #12场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-09-16&#xff08;周六&#xff09; #3场比赛2023-09-17…

【FPGA项目】进阶版沙盘演练——报文收发(报文处理、CDC、CRC)

前言 书接上文【FPGA项目】沙盘演练——基础版报文收发_子墨祭的博客-CSDN博客&#xff0c;前面我们做了基础版的报文收发&#xff0c;相信对逻辑设计有了一定的认知&#xff0c;在此基础上&#xff0c;继续完善一个实际报文收发可能会遇到的一些处理&#xff1a; 报文处理握手…

公交查询系统

目录 需求分析 1 概述 2 课题分析 3 实现功能步骤 4 项目背景 概要设计 1 系统流程图. 2 功能模块. 3 各功能模块 4 数据存储 5 类设计 三、详细设计 1公交线路查询系统用户界面 2公交信息存储模快 3公交信息查询模块 4用户信息输入和输出模块 四、调试分析 五、使用说明 六、…

STM32外部复位IC与看门狗冲突,无法复位问题解决方案

使用STM32H743制作了一款飞控&#xff0c;外部复位IC采用MAX809STR,打板完后&#xff0c;烧录飞控固件后大量板子无法正常启动&#xff0c;怀疑是晶振没有起振或MCU未焊接好&#xff0c;检查后均焊接正常&#xff0c;编写裸机LED定时闪烁验证程序可正常运行。经网上查询资料锁定…

Python 环境搭建,集成开发环境IDE: PyCharm

Python 环境搭建,集成开发环境IDE: PyCharm 一、Python 环境搭建二、Python下载三、Python安装四、环境变量配置五、Python 环境变量六、运行Python1、交互式解释器&#xff1a;2、命令行脚本3、集成开发环境&#xff08;IDE&#xff1a;Integrated Development Environment&am…

Hadoop-Hive

1. hive安装部署 2. hive基础 3. hive高级查询 4. Hive函数及性能优化 1.hive安装部署 解压tar -xvf ./apache-hive-3.1.2-bin.tar.gz -C /opt/soft/ 改名mv apache-hive-3.1.2-bin/ hive312 配置环境变量&#xff1a;vim /etc/profile #hive export HIVE_HOME/opt/soft/hive…

软件测试的基本流程是什么?软件测试流程详细介绍

软件测试和软件开发一样&#xff0c;是一个比较复杂的工作过程&#xff0c;如果无章法可循&#xff0c;随意进行测试势必会造成测试工作的混乱。为了使测试工作标准化、规范化&#xff0c;并且快速、高效、高质量地完成测试工作&#xff0c;需要制订完整且具体的测试流程。 01…

JavaScript的DOM操作(二)

一、元素的特性attribute 1.元素的属性和特性 前面我们已经学习了如何获取节点&#xff0c;以及节点通常所包含的属性&#xff0c;接下来我们来仔细研究元素Element。 我们知道&#xff0c;一个元素除了有开始标签、结束标签、内容之外&#xff0c;还有很多的属性&#xff0…

Flutter 使用pageview无缝隙自动轮播教程

导入要使用的轮播图片 List<String> imagesa ["assets/images/car_qidian.jpg","assets/images/car_bg.jpg","assets/images/car_bg.jpg","assets/images/car_bg.jpg","assets/images/car_bg.jpg","assets/imag…

【算法与数据结构】450、LeetCode删除二叉搜索树中的节点

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题首先要分析删除节点的五种情况&#xff1a; 1、没有找到节点2、找到节点 左右子树为空左子树为空…

docker容器管理-实操命令

本单元主要是在docker镜像管理下进一步的培训学习文档。 docker镜像管理-实操_忍冬行者的博客-CSDN博客 四.容器管理 1.运行一个容器 docker container run --name c1 -it nginx:latest /bin/sh 2.后台运行一个容器 docker container run --name c1 -it -d nginx:latest 3.查…

微信小程序项目开发Day1

没接触过&#xff0c;直接看视频学习&#xff1a; 千锋教育微信小程序开发制作前端教程&#xff0c;零基础轻松入门玩转微信小程序_哔哩哔哩_bilibili千锋教育微信小程序开发制作前端教程&#xff0c;零基础轻松入门玩转微信小程序共计56条视频&#xff0c;包括&#xff1a;学…

List 获取前N条数据

1.使用for循环遍历 public static void main(String[] args) {int limit 5;List<Integer> oldList Lists.newArrayList(1, 2, 3, 4, 5, 6, 7);List<Integer> newList Lists.newArrayList();if (oldList.size() < limit) {newList.addAll(oldList);return;}fo…

软件工程课件

软件工程 考点概述软件工程概述能力成度模型能力成熟度模型集成软件过程模型逆向工程软件需求需求获取数据流图 需求定义 考点概述 重点章节 软件工程概述 之前老版教程的&#xff0c;之前考过 能力成度模型 记忆 能力等级 和 特点 能力成熟度模型集成 相比于CMM&#xff0c;第…

结合el-input、el-select实现纯前端过滤树形el-table数据

样式图示 1.搜索实现方法 const searchBtn async () > {// 获取table列表数据接口const res await Api.menuList({paging: false})if (res.code 200) {// 把树形结构转成扁平结构let result treeToArray(res.data)// 处理搜索框中数据进行table显示项过滤if(commonData…

分享!JetBrains IDE中的GitLab支持

GitLab是流行的基于git的软件开发和部署平台之一&#xff0c;虽然很长一段时间以来&#xff0c;所有基本git操作都已经可以通过GitLab实现&#xff0c;但GitLab集成仍是JetBrains社区的一大最热门请求。为此&#xff0c;JetBrains团队今年与GitLab联手提供了这种类型的集成。 …

2023年华为杯研究生数学建模竞赛辅导

2023年华为杯研究生数学建模竞赛辅导 各研究生培养单位&#xff1a; 中国研究生数学建模竞赛作为教育部学位管理与研究生教育司指导&#xff0c;中国学位与研究生教育学会、中国科协青少年科技中心主办的“中国研究生创新实践系列大赛”主题赛事之一&#xff0c;是一项面向在校…

使用阿里PAI DSW部署Stable Diffusion WebUI

进入到网址https://pai.console.aliyun.com/里边。 点击创建实例。 把实例名称填写好&#xff0c;选择GPU规格&#xff0c;然后选择实例名称是ecs.gn6v-c8g1.2xlarge。 选择stable-diffusion-webui-env:pytorch1.13-gpu-py310-cu117-ubuntu22.04&#xff0c;然后点击下一步。…

如何利用软文推广进行SEO优化(打造优质软文,提升网站排名)

在当今的互联网时代&#xff0c;SEO优化成为了网站推广的关键。而软文推广作为一种有效的推广方式&#xff0c;其优点不仅仅局限于SEO&#xff0c;还可以带来更多的曝光和用户流量。本文将深入探讨如何做好软文推广&#xff0c;从而提升网站排名和流量。 了解目标受众群体 内容…

springboot集成excel导入导出

1、引入依赖 <dependency><groupId>com.pig4cloud.excel</groupId><artifactId>excel-spring-boot-starter</artifactId><version>1.2.7</version> </dependency> 2、导出 ResponseExcel(name "测试列表") Post…