面试必问:HashMap底层原理详解+用Java代码手写简易实现HashMap

本文详细介绍了HashMap的基本原理,包括哈希算法、哈希碰撞的解决方法,以及从JDK7到JDK8中从链表到红黑树的转变原因。通过对HashMap的内部数据结构和算法的探讨,揭示了其高效查询的本质,并提供了手写HashMap的实现思路。
摘要由CSDN通过智能技术生成

HashMap简介

简单来说,hashmap是一种用于存储key-value键值对的数据结构。

快速入门

存储:put()
查询:get()

技术的本质

我们说程序设计的本质=数据结构+算法
hashmap在jdk7中使用的数据结构是:数组+链表
hashmap在jdk8中使用的数据结构是:数组+链表+红黑树
算法:哈希算法

数据结构:数组、链表

在这里插入图片描述

  • 数组:采用一段连续的存储单元来存储数据
    • 特点:查询快,插入删除慢(查询O(1),删除插入O(N))
    • jdk中ArrayList的底层实现用到了数组

在这里插入图片描述

  • 链表:是一种物理存储单元上非连续,非顺序的存储结构
    • 特点:插入删除快,查找慢(插入删除时间复杂度O(1),查找遍历时间复杂度为O(N))
    • jdk中LinkedList的底层实现用的就是链表

算法:哈希算法(散列)

hashmap底层由哈希算法来实现,下面会做详细介绍

哈希算法和哈希碰撞

哈希算法简介

哈希算法(也叫散列),就是把任意长度值(key)通过散列算法变换成固定长度的key(地址)通过这个地址进行访问的数据结构
它通过把关键码映射到一个表中的一个位置来访问记录,以加快查找的速度。

Hashcode:通过字符串算出他的ascii码,进行mod(取模),算出哈希表中的下标,取模的值n为数组的长度
以下图为例:字符串"lies"的哈希运算为429 % 10 = 9(假设n为10)
那么就将字符串"lies"存储到数组下标为9的位置

思考:为什么要取模操作
答:为了节省数组空间
在这里插入图片描述

哈希碰撞(哈希冲突)

思考:上述取模的操作会带来什么问题
不同key的哈希值取模之后可能会有相同的计算结果,造成哈希碰撞

什么是哈希碰撞?

在这里插入图片描述
如上图所示,"lies"和"foes"两个不同的key在hashmap中都可以储存在数组下标为9的位置,此时出现了哈希冲突。

如何用链表数据结构解决

采用链表头插法,将最新计算出的哈希值存储到对应的数组下标中,判断数组对应的index是否为空,若为空则直接存储,若不为空,则让最新的node节点的next指向原本index下的结点,然后将最新的头结点覆盖原本array[index]的值
在这里插入图片描述

手写实现hashmap

定义接口规范,后面会创建类将其具体实现

package com.bnuz.hashmap;

public interface Map<K,V> {
   
    V put(K k,V v);
    V get(K K);
    int size();

    interface Entry<K,V>{
   
        K getKey();
        V getValue();
    }
}

hashmap的实现 核心方法为put()和get()
遍历链表查询这里采用了递归的写法

package com.bnuz.hashmap;

public class HashMap<K
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值