Java手写HashMap

之前面试拼多多的时候问到了,但是没练习过。
直接上代码

import java.util.Objects;/*** ClassName: MyHashMap* PackageName: com.joshua* @author: Joshua Lee* @create: 2024/6/10 - 20:21* @description: 自己实现HashMap*/
public class MyHashMap<K, V> {static class Node<K, V> {private K key;private V value;private Node<K, V> next;// 注意:构造方法中,Node后面不用跟 <K,V>、里面也要用this给指定的属性赋值public Node(K key, V value) {this.key = key;this.value = value;}// 注意:构造方法中,Node后面不用跟 <K,V>、里面也要用this给指定的属性赋值public Node(K key, V value, Node<K, V> next) {this.key = key;this.value = value;this.next = next;}}// 默认容量final int DEFAULT_CAPACITY = 16;// 默认装载因子final float LOAD_FACTOR = .75f;// 已经放入map中的元素个数private int size;// 底层存放数据的数据结构。创建数组时,是有 <K, V>[] 的private Node<K, V>[] buckets;/*** 创建map的无参构造方法。*/public MyHashMap() {buckets = new Node[DEFAULT_CAPACITY];size = 0;}/*** 创建指定容量的map* @param capacity 指定的容量*/public MyHashMap(int capacity) {buckets = new Node[capacity];size = 0;}/*** 获得当前键key在长度为length的Node数组中的索引下标* @param key 当前键* @param length 当前底层数组长度*/int getIndex(K key, int length) {int hashCode = key.hashCode();int index = hashCode % length;return Math.abs(index);}/*** 往map中放置数据* @param key 想放置的key* @param value 想放置的value*/public void put(K key, V value) {// 检查是否需要扩容,需要扩容则扩容if (size >= buckets.length * LOAD_FACTOR) {resize();}// 将数据放到数组中putVal(key, value, buckets);}/*** 将key、value键值对放入Node数组 table中* @param key 想放置的key* @param value 想放置的value* @param table 当前的底层Node数组*/private void putVal(K key, V value, Node<K, V>[] table) {// 获得当前key在buckets中的indexint index = getIndex(key, table.length);Node<K, V> node = table[index];// 如果当前该位置还没有数据if (node == null) {table[index] = new Node<>(key, value);// 成功将一个元素放到底层数组中,就将size+1size++;return;}// 如果当前数组的index位置上已经有数据了// 就遍历整条链表,看看是否存在key为要放置的key的结点,如果存在,则覆盖掉原来结点的valuewhile (node != null) {if (node.key == key || Objects.equals(node.key, key)) {node.value = value;return;}node = node.next;}// 至此,index处的链表里面没有key为传入的key的结点,就使用头插法,将当前的key、value、index处的结点引用封装到Node结点中table[index] = new Node<>(key, value, table[index]);// 成功将一个元素放到底层数组中,就将size+1size++;}/*** 进行底层数组扩容*/private void resize() {Node<K, V>[] newBuckets = new Node[buckets.length * 2];rehash(newBuckets);buckets = newBuckets;}/*** 将原始数组buckets中的每个位置的结点、链表重新hash,放到新的数组newBuckets中* @param newBuckets 新的放Node节点的底层数组*/private void rehash(Node<K, V>[] newBuckets) {// 当前map的size要归0,因为在调用putVal()中,会执行size++size = 0;for (int i = 0; i < buckets.length; i++) {Node<K, V> node = buckets[i];if (node == null) {continue;}while (node != null) {putVal(node.key, node.value, newBuckets);node = node.next;}}}/*** 从当前map中获取key对应的value* @param key 要查找的key* @return key对应的value。如果key不存在,则返回null*/public V get(K key) {int index = getIndex(key, buckets.length);Node<K, V> node = buckets[index];if (node == null) {return null;}while (node != null) {if (node.key == key || Objects.equals(node.key, key)) {return node.value;}node = node.next;}return null;}/*** 获取当前map中有多少个元素*/public int size() {return this.size;}public static void main(String[] args) {MyHashMap<String, Integer> map = new MyHashMap<>();map.put("abc", 10);map.put("def", 20);System.out.println(map.get("abc"));System.out.println(map.get("de"));System.out.println(map.get("def"));System.out.println(map.size());}
}

注意点

静态内部类Node

key、value是泛型类型,当然面试时,可能就直接指定一个类型就可以了。
由三个属性:key、value、next,再加两个Node的构造方法

MyHash

属性:默认大小:DEFAULT_CAPACITY、装载因子:LOAD_FACTOR、已装入的Node节点个数:size、底层放Node节点的NodeNode<K, V>[] 数组:buckets
方法:构造方法、获取key对应的索引的方法:getIndex(),放置数据的方法:put()、putVal(),扩容的 方法:resize()、rehash(),获取key对应的value的方法:get(),获取数据个数的方法:size()。

因为底层数组是泛型,所以,有几处写法需要注意

定义buckets成员时:private Node<K, V>[] buckets;<K, V>
给buckets赋值时:buckets = new Node[capacity]; 没有 <K, V>

定义Node节点时:Node<K, V> node = new Node<>(key, value);

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

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

相关文章

ASP.NET的WebService跨域CORS问题解决方案

ASP.NET WebService 跨域(CORS, Cross-Origin Resource Sharing)问题通常发生在当您尝试从不同的源(域名、协议或端口)调用 WebService 时。浏览器由于安全原因,默认会阻止此类跨域请求。为了解决这个问题,您需要在 WebService 服务器端配置 CORS。 以下是在 ASP.NET We…

域内攻击 ----> DCSync

其实严格意义上来说DCSync这个技术&#xff0c;并不是一种横向得技术&#xff0c;而是更偏向于权限维持吧&#xff01; 但是其实也是可以用来横向&#xff08;配合NTLM Realy&#xff09;&#xff0c;如果不牵强说得话&#xff01; 那么下面&#xff0c;我们就来看看这个DCSyn…

[Vue3:axios]:实现登录跳转页面展示列表(查看教师所承担课程的学生选课情况)

文章目录 一&#xff1a;前置操作项目结构&#xff1a; 二&#xff1a;登录页面主要流程说明运行截图前端代码Login.vue 三&#xff1a;列表页面交互逻辑&#xff1a;涉及页面Page02.vue &#xff08;登录成功跳转学生选课页面&#xff09;运行截图 一&#xff1a;前置操作 ht…

数据结构:插入排序和希尔排序

插入排序 逆序的情况下&#xff1a; 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(1) 顺序的情况下&#xff1a; 时间复杂度&#xff1a;O(N) 空间复杂度…

将字符串str1复制为字符串str2

定义两个字符数组str1和str2&#xff0c;再设两个指针变量p1和p2&#xff0c;分别指向两个字符数组中的有关字符&#xff0c;通过改变指针变量的值使它们指向字符串中的不同的字符&#xff0c;以实现字符的复制。编写程序&#xff1a; 运行程序&#xff1a; 程序分析&#xff1…

【T3】畅捷通T3软件查询明细账等账簿,出现某些列串位置。

【问题描述】 查询畅捷通T3软件科目明细账的时候&#xff0c; 出现某些行的数据串位置&#xff0c; 摘要、金额、方向都没有在对应的列。 【解决方案】 根据跟踪发现&#xff0c;最终在客户档案上发现问题。 数据串位中对应的客户名称、简称中的对后面多了一个【tab】键的空格…

从数组和指针笔试题深度理解 sizeof 和 strlen

一、sizeof 和 strlen 的区别 a.sizeof sizeof 计算变量所占内存内存空间大小的&#xff0c;单位是字节&#xff0c;如果操作数是类型的话&#xff0c;计算的是使用类型创建的变量所占内存空间的大小。sizeof 只关注占用内存空间的大小&#xff0c;不在乎内存中存放什么数据。…

Mysql学习(八)——多表查询

文章目录 五、多表查询5.1 多表关系5.2 多表查询概述5.3 内连接5.4 外连接5.5 自连接5.6 联合查询5.7子查询5.8 总结 五、多表查询 5.1 多表关系 概述&#xff1a;项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;…

Deepin安装PostGresql

最近要把开发环境完全从Windows移到Deepin上&#xff0c;本次介绍在Deepin借助apt-get安装和配置数据库。同时可以用Dbever提供图形化管理工具。 安装PostGreSQL数据库和创建数据库 #安装postgresql zhanglianzhuzhanglianzhu-PC:/$ sudo apt-get install postgresql-16 正在…

STM32CubeIDE使用过程记录

最近在做一款机器人的开发&#xff0c;使用到了STM32CubeIDE&#xff0c;这里记录一些使用技巧方便后续查阅。 STM32CubeIDE使用过程记录 快捷键开启代码自动补全功能看门狗设置CRC设置IO口取反定时器设置 及 定时器中断外部中断GPIO配置STC15单片机GPIO模式配置片内闪存&#…

完美落地的自动化测试框架(pytest):智能生成?业务依赖?动态替换?报告构建?你来,这儿有!

前言 随着软件测试行业的快速发展&#xff0c;去测试化、全员测开化的趋势&#xff0c;技术测试已成为确保软件质量不可或缺的一环。 但对于许多没有代码基础或缺乏系统性自动化知识的测试人员来说&#xff0c;如何入手并实现高质量的自动化测试成为了一个挑战。 为此&#xff…

【Java01】Java 17中的switch

Java 17中的switch 1. 新式switch语句的格式 switch (expression) {case value1 -> 表达式、代码块;case value2, value3 -> 表达式、代码块;// ...default -> 表达式、代码块; }case后允许同时放置多个valuecase value后的冒号变箭头case后的代码块不需要breakcase…

element-plus ui的使用说明

Element Plus UI的使用说明如下&#xff1a; 1. 安装Element Plus 首先&#xff0c;确保你的项目是基于Vue 3的。你可以使用npm或yarn来安装Element Plus。 使用npm安装&#xff1a; npm install element-plus --save 使用yarn安装&#xff1a; yarn add element-plus 2…

第54集《摄大乘论》

讲大家打开《讲义》第一八0页&#xff1a; 戊二、广能引发(分二&#xff1a;己一十难行&#xff1b;己二四作业) 己一、十难行(分二&#xff1a;庚一略释十难释&#xff1b;庚二重释随觉难行) 庚一、略释十难释(分二&#xff1a;辛一标数&#xff1b;辛二列释) 我们这一科讲…

Vue 路由实现组件切换

Vue 路由实现组件切换 不会就问 qq3131015733 觉得讲得不好了&#xff0c;麻烦喷一下&#xff0c;感谢反馈。 下拉菜单乃个项目的地址&#xff1a;https://1024code.com/ide/rzaqrgx 文章目录 Vue 路由实现组件切换前置知识入门效果展示安装依赖文件目录代码Home.vue代码Abou…

C语言 图形化界面方式连接MySQL【C/C++】【图形化界面组件分享】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一.配置开发环境 二…

基于Java-SpringBoot-VUE-MySQL的企业财务报销系统

基于Java-SpringBoot-VUE-MySQL的企业财务报销系统 登陆界面 联系作者 如需本项目源代码&#xff0c;可扫码或者VX:bob1638 联系作者。 主页-02 系统功能持续更新中。。。 介绍 本系统是采用现代信息技术手段&#xff0c;采用JAVA开发语言&#xff0c;VUE语言&#xff0c;HTML语…

python导入非当前目录(如:父目录)下的内容

在开发python项目时&#xff0c;通常会划分不同的目录&#xff0c;甚至不同层级的目录&#xff0c;这时如果直接导入不在当前目录下的内容时&#xff0c;会报如下的错误&#xff1a;ModuleNotFoundError: No module named miniai其实这里跟操作系统的环境变量很类似的&#xff…

WMS仓储管理系统高效驱动制造企业物料管理

在现代制造业的快速发展中&#xff0c;仓储管理作为供应链的核心环节&#xff0c;其效率直接影响到企业的生产力和市场竞争力。随着科技的进步&#xff0c;实施WMS仓储管理系统逐渐成为推动仓储管理向智能化转型的关键力量。本文将深入探讨WMS仓储管理系统如何以创新的方式驱动…

Spring AI 第三讲Embeddings(嵌入式) Model API 第一讲Ollama 嵌入

有了 Ollama&#xff0c;你可以在本地运行各种大型语言模型 (LLM)&#xff0c;并从中生成嵌入。Spring AI 通过 OllamaEmbeddingModel 支持 Ollama 文本嵌入。 嵌入是一个浮点数向量&#xff08;列表&#xff09;。两个向量之间的距离可以衡量它们之间的相关性。距离小表示关联…