HashMap

Posted 一梦三十载

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashMap相关的知识,希望对你有一定的参考价值。


HashMap可以接受null键值和值,而Hashtable则不能;HashMap是非synchronized;HashMap很快;以及HashMap储存的是键值对
HashMap是基于hashing的原理,使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,先对键调用hashCode()方法,返回的int类型的hashCode值用于找到bucket位置来储存Entry对象。”(HashMap是在bucket中储存键对象和值对象,作为Map.Entry)
当两个对象的hashcode相同,所以它们的bucket位置相同,‘碰撞’会发生。因为HashMap使用链表存储对象,这个Entry(包含有键值对的Map.Entry对象)会存储在链表中

问:

1、Entry是什么
     Entry一个单向链表 Entry实现了Map.Entry接口

2、如果两个键的hashcode相同,如何获取值对象?
     当我们调用get()方法,HashMap会使用键对象的hashcode找到bucket位置,然后获取值对象。
     找到bucket位置之后,会调用keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象

3、hashmap怎么解决碰撞问题
     HashMap本质就是数组+链表结构
     HashMap里面没有出现hash冲突时,没有形成单链表时,hashmap查找元素很快,get()方法能够直接定位到元素,但是出现单链表后,单个bucket 里存储的不是一个                Entry,而是一个 Entry 链,系统只能必须按顺序遍历每个 Entry,直到找到想搜索的 Entry 为止——如果恰好要搜索的 Entry 位于该 Entry 链的最末端(该 Entry 是最        早放入该 bucket 中),那系统必须循环到最后才能找到该元素。

     在调用HashMap的put方法或get方法时,都会首先调用hashcode方法,去查找相关的key,当有冲突时,再调用equals方法。hashMap基于hasing原理,通过put和get      方法存取对象。当我们将键值对传递给put方法时,他调用键对象的hashCode()方法来计算hashCode,然后找到bucket(哈希桶)位置来存储对象。当获取对象时,通      过键对象的equals()方法找到正确的键值对,然后返回值对象。
     HashMap使用链表来解决碰撞问题,当碰撞发生了,对象将会存储在链表的下一个节点中。hashMap在每个链表节点存储键值对对象。当两个不同的键却有相同的            hashCode时,他们会存储在同一个bucket位置的链表中。键对象的equals()来找到键值对。

    简单理解:根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面  ,通过数组下标取出链表,遍历链表用           equals取出对应key的value

4、什么是单向链表
     链表是由一些节点构成的,这些节点之间由指针连接,形成了一个链式结构。最基本的链表节点只需要存储当前节点的值,和一个指向下一节点的指针。由这种只存储      下一节点地址的链表节点构成的链表被称为单向链表。

     Entry<k,v>可以看出该类是用来存放键值对的,并且通过next指向下一个实例实现链表结构。
    在HashMap中定义了一个Entry类型的数组(Entry[ ] table ),当要put key-value时,先通过key计算hashcode作为该数组的下标,然后将实例化的Entry<>置于此位         置。若发生冲突(不同的key对应相同的下标)则通过Entry中的next实现链接。
    所以HashMap中的Entry<k,v>类型是以链表的形式存放键值对的。

5、如果HashMap的大小超过了负载因子(load factor)定义的容量,怎么办?
     默认的负载因子大小为0.75,也就是说,当一个map填满了75%的bucket时候,和其它集合类(如ArrayList等)一样,将会创建原来HashMap大小的两倍的bucket数组,        来重新调整map的大小,并将原来的对象放入新的bucket数组中。这个过程叫作rehashing,因为它调用hash方法找到新的bucket位置。

-----------------------------------------------------------------------------------------------------------------

总结
当往hashmap中put元素的时候,先根据key的hash值得到这个元素在数组中的位置(即下标),然后就可以把这个元素放到对应的位置中了。如果这个元素所在的位子上已经存放有其他元素了,那么在同一个位子上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。从hashmap中get元素时,首先计算key的hashcode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。

HashMap的工作原理
HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。

当两个不同的键对象的hashcode相同时会发生什么? 它们会储存在同一个bucket位置的链表中。键对象的equals()方法用来找到键值对。

HashMap的好处非常多,在电子商务的应用中使用HashMap作为缓存。出于性能的考虑,会经常用到HashMap和ConcurrentHashMap。

以上是关于HashMap的主要内容,如果未能解决你的问题,请参考以下文章

HashMap学习

MAP

HashMap

HashMap问答

Map的实现

HashMapConcurrentHashMapHashTable