前言
今天看面经看得到大厂面试题,说实话HashMap感觉真的很了解,源码看了也很多遍了,相信大部分小伙伴都能有这个程度。但是,突然给你来这么一手,还是有点懵圈!所以,今天给各位小伙伴整理一下,帮助各位掌握!
正常来说,面试时遇到手写HahsMap,基本上都是要求实现get、put方法,我就稍微全面那么一点,再加一个remove方法。
重点掌握
HashMap在JDK7、JDK8中不安全的地方到底在哪里???
好了好了,话不多说,我们开始吧。
撸起袖子开始造
实现数组 + 链表
众所周知,HashMap无论是JDK7还是JDK8,底层都是数组 + 链表,只是JDK8多了一个红黑树,按道理讲不会还有手写红黑树的吧,😰。
既然是数组 + 链表,那我就实现一个链表
参考JDK8源码
我们就没必要那么高级,🤭
1 | java复制代码static class Node { |
链表有了,就再来个数组(面试过程基本上不要求扩容,所以我们就直接给数组定义一个差不多的值就OK了)
1 | java复制代码private final int CAPACITY = 10000; |
实现获取Key对应数组索引的方法
参考源码
1 | java复制代码public V get(Object key) { |
图示讲解
实现
因为int为基本数据类型,所以我们用==Integer.hashCode(int value)==
而Integer.hashCode(int value),返回的其实就是你传入的值
1 | java复制代码public static int hashCode(int value) { |
1 | python复制代码private int getIndex(int key) { |
实现get方法
流程很简单
- 获取到传入的 key 的对应的索引下标
- 拿到对应下标对应的链表首节点
- 非空判断
- 如果链表首节点的Key是目标Key,那么直接返回对应的Value值;如果不是,那么对链表进行遍历获取,如果遍历完成都没有去返回Value值,那么说明HashMap没有这个数据,那么就返回-1.
1 | java复制代码public int get(int key) { |
参考源码
1 | python复制代码final Node<K,V> getNode(int hash, Object key) { |
实现put方法
流程介绍
注意:我们需要保存前一个节点,这样如果put的是一个新键值对的话,我们可以获取到链表的最后一个不为null的节点
- 获取Key对应的索引值
- 非空判断,如果为空,说明该索引对应的链表为空,可直接创建新节点添加
- 不为空则循环遍历,遍历过程更新 prev ,如果遍历过程中找到则返回value值
- 如果遍历完成还没有返回,说明没有该节点可以添加,那么根据 prev 是否为null进行添加;
1 | java复制代码public void put(int key, int value) { |
实现remove方法
大致流程跟get方法差不多,区别就是我们我们需要==保存需要删除节点的前一个节点==
1 | python复制代码 public void remove(int key) { |
测试一下
1 | java复制代码public static void main(String[] args) { |
完整代码
1 | java复制代码public class MyHashMap { |
CSDN独家福利降临!!!
最近CSDN有个独家出品的活动,也就是下面的《Java的全栈知识图谱》,路线规划的非常详细,尺寸 是870mm x 560mm
小伙伴们可以按照上面的流程进行系统的学习,不要像我当初一样没人带自己随便找本书乱学,系统的有规律的学习,它的基础才是最扎实的,在我们这行,《基础不牢,地动山摇》尤其明显。
最后,如果有兴趣的小伙伴们可以酌情购买,为自己的未来铺好道路!!!
最后
我是 Code皮皮虾,一个热爱分享知识的 皮皮虾爱好者,未来的日子里会不断更新出对大家有益的博文,期待大家的关注!!!
创作不易,如果这篇博文对各位有帮助,希望各位小伙伴可以==一键三连哦!==,感谢支持,我们下次再见~
分享大纲
更多精彩内容分享,请点击 Hello World (●’◡’●)
本文转载自: 掘金