HashMap的实现原理

来源:互联网 发布:淘宝达人名字大全 编辑:程序博客网 时间:2024/06/06 13:10

hashMap是map接口的一个实现类,常用于存储键值对,HashMap在底层采用一个Entry[] 数组来保存所有的key-value对,一个键值对就是一个Enry。

当调用put()方法存储Entry对象的时候,首先会将Entry中的key值的hashcode值输入hash算法,hash算法会返回一个hash值,这个值决定了Entry在table数组中的存储位置(indexFor()实际上返回hash值和数组长度的按位与)。如果两个 Entry 的 key 的 hashCode() 返回值相同,那它们的存储位置也相同,这就产生了冲突,这时如果这两个 Entry 的 key 通过 equals 比较返回 true,新添加 Entry 的 value 就会覆盖集合中原有 Entry 的 value(key不会覆盖),如果这两个 Entry 的 key 通过 equals 比较返回 false,新添加的 Entry 会与集合中原有 Entry 形成 Entry 链,而且新添加的 Entry 位于 Entry 链的头部并且指向原有的 Entry 对象。

当调用get()方法读取value时,只要先计算出该 key 的 hashCode() 返回值,在根据该 hashCode 返回值找出该 key 在 table 数组中的索引,然后取出该索引处的 Entry,最后返回该 key 对应的 value 就OK了。如果存储数据的时候没有发生冲突的话,table数组中对应的位置就只有一个entry对象,但是发生了冲突的话,只能按顺序遍历Entry链,直到找到想搜索的 Entry 为止(输入的key值和Entry中的key值hashCode相同,并且equals返回true的话,才算找到)。

在创建hashMap的时候,可以指定初始化容量和负载因子,数组容量和负载因子决定了阈值,如果table数组中放入数据的总量大于阈值的话,HashMap会自动调用 resize 方法增大一倍容量,这个阈值就是数组容量和负载因子的乘积。默认的初始化容量是16,负载因子是0.75,增大负载因子可以减少 Hash 表占用的内存空间,但是会增加冲突的次数,增加查询数据的时间开销,减小负载因子会减少冲突次数,但会增加 Hash 表所占用的内存空间,hashMap实现了时间和空间的平衡。

归纳起来简单地说,HashMap 在底层将 key-value 当成一个整体进行处理,这个整体就是一个 Entry 对象。HashMap底层采用一个 Entry[] 数组来保存所有的key-value 对,当需要存储一个 Entry 对象时,会根据 Hash 算法来决定其存储位置;当需要取出一个 Entry 时,也会根据 Hash 算法找到其存储位置,直接取出该 Entry。由此可见:HashMap 之所以能快速存、取它所包含的 Entry,完全类似于现实生活中母亲从小教我们的:不同的东西要放在不同的位置,需要时才能快速找到它。 




参考链接:http://alex09.iteye.com/blog/539545/

0 0