关于hashmap

来源:互联网 发布:长相土气的女明星知乎 编辑:程序博客网 时间:2024/06/04 19:45

HashMap是基于哈希表的map接口的非同步实现。允许使用null值和null键。不保证映射的顺序,特别是它不保证该顺序恒久不变。

HashMap实际上是一个链表散列的数据结构,即数组和链表的结合体。底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,就会初始化一个数组。

1. 存取:

当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置,即下标,如果数组改为支行已经存放有其他元素了,那么这个位置上的元素将以链表的形式存放,尽享福的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。

从HashMap中get元素的时候,首先计算key的hashCode,找到数组中对应位置的某一元素,然后通过key的equals方法在队形位置的链表中找到需要的元素。

HashMap在底层将key-value单程一个整体进行处理,这个整体就是一个Entry对象。HashMap底层采用一个entry[]数组来保存所有的key-value对。当需要存储一个Entry对象时,会根据hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置,取出一个entry时,也会根据哈说算法找到其在数组中的春初位置,在根据equals方法从猜位置上的链表中取出该Entry。

2. HashMap的resize(rehash):

当HashMap中的元素越来越多的时候,hash冲突的几率也就越来越高,因为数组的长度时固定的。所以为了提高查询的效率,就要对HashMap的数组进行扩容,数组扩容的这个操作会出现在ArrayList中,这是一个常用的操作。在HashMap数组扩容之后,最消耗性能的点就出现了,数组中的数据必须重新计算其在新数组中的位置,并放进去,这个就是resize。

当HashMap中的元素个数超过数组大小*loadFactor的时候,就会进行数组扩容,loadFactor的默认值时0.75,这是一个这种的取值。默认情况下数组大小为16,当HashMap中的元素个数超过16*0.75=12的时候,就会吧数组的大小扩展为2*16=32,即扩大一倍,这是一个非常小猴性能的操作,如果我们已经预知HashMap中元素的个数,那么预设元素的个数就能够有效的提高HashMap的性能。

HashMap的api指出:

由所有的HashMap类的collection视图方法 所返回的爹台期都是快速失败的,在迭代器创建之后,如果从结构上对映射进行修改,除非通过迭代器本身的remove方法,其他任何时间任何方式的修改,迭代器都将抛出ConcurrentModificationException。因此,面对并发的修改,爹台期很快就会完全失败,而不冒在将来不确定的时间发生任意不确定给行为的风险。

0 0
原创粉丝点击