集合框架(十)----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的核心思路大致就是这些了!里面还是有不少东西没有搞懂,待研究!

posted @ 2016-09-24 18:47  DeadGhost  阅读(170)  评论(0编辑  收藏  举报