-
集合框架(十)----HashMap
关于HashMap的继承体系,可以查看上一篇博文!
然后,是时候(装逼了)展现真正的技术了:
首先我们打开Map<K,V>接口瞅瞅,发现接口中除了定义了一大坨规范外啥都没有!于是我们接着打开AbstractMap<K,V>
看看,大致猫一眼后:几个常用方法的实现都很简单啊,没意思!接着当然是打开传说中的HashMap<K,V>了!!!
首先截张图压压惊:
什么?这么多?这怎么读?不知道你怕不怕,反正我是怂了!虽然怂了,但不能放弃啊(哥可是个有始有终的人)!于是,我们从关键部分开始,尽量学到其核心部分,其他的就暂时不用管了!
一个类的开始的核心部分当然是构造方法了,然后聪明的我找到了构造方法中最核心的一个构造方法:
图中我标出了几个关键点,这个构造方法中有两个参数,分别是初始容量和加载因子。
那么,问题来了。What 初始容量and加载因子???下图是来自jdk1.6的注释文档的解释:
至于这两货的默认值,可在源码的开头部分容易的找到!
然后,还有一个不认识的玩意:`this.threshold = tableSizeFor(initialCapacity);`
于是,ctrl+鼠标左键(本人用的eclispe。idea,NetBean都是这个快捷键)找到这个方法:
瞅了瞅,不就是位运算吗?有啥了不起,对不对!但是,为什么要这么做呢?虽说会位运算,但毕竟用的少,不是很熟悉,而且还有或运算,不知道你能不能看懂,反正我是完全懵逼了!但是,不知道它的原理,得知道它的用途啊,要不然没办法继续啊!看到我标出的那段英文注释了吗?这就是大神给我们这些菜鸟的解释!大致意思是:返回一个接近参数的一个2的n次方数。
虽说看完了构造方法,但构造方法中仅仅是确定了对象的加载因子和初始容量,这两货到底有啥用啊?HashMap到底怎样存储数据啊?迷雾重重啊!那接下来该读哪里呢?当然是put方法了!为什么?你在使用HashMap时,第一步创建一个HashMap类的实例对象;第二步是干什么??当然是。。。嗯,没错,让我们看看传说中的put方法:
What???Lets ctrl+鼠标左键:
真TMD长,这里不得不说两句,写这部分源码的作者竟然把表的初始化和键值的添加放在一起,看到红色框框的那句判断了吗?你每次添加一组值,便要进行一次判断,简直卧槽!分开写多好啊,像前面List的实现都是在构造方法中初始化的!
然后看看用红色圈圈圈起来的东西,我们ctrl+鼠标左键:
很显然,这货是用来存储元素的!并用覆写了hashCode()方法!看到这个Node有没有想到什么??我可是想到了很多呢,比方说:Linked
怎么样?是不是很像呢!没错,就是链表!
接下来,让我们认识认识那个令人讨厌的resize()方法:
看到没,因为没有单独初始化,所以在这里还要判断!看到我标出的注释了吗!大致意思是:`初始化或让容量加倍`!
先看看怎么初始化的:
然后再瞅瞅如何使容量增大:
大致思路就是,容量变为原来的2倍,然后将旧表中的数据都复制到新表中!
然后看看如何添加键值(突然发现这个方法真TMD流弊):
看到这个不知道你有没有想到什么,我可是又想到了好多东西呢,比方说:
没错,邻接表,像不像,像不像!但是,从get()方法来看,人家的下标取值是这样的:
高大上啊,有没有!完全懵逼啊!懵逼就懵逼吧!毕竟高大上!
那么,HashMap的核心思路大致就是这些了!里面还是有不少东西没有搞懂,待研究!
-
相关阅读:
ERROR: epmd error for host "yourhostname": timeout
leetcode485
leetcode463
leetcode496
leetcode344
leetcode412
leetcode500
leetcode476
leetcode557
leetcode461
-
原文地址:https://www.cnblogs.com/realsoul/p/5903279.html
Copyright © 2020-2023
润新知