哈希表
哈希表的主干为数组,数组中根据下标查找元素,一次定位就可以达到。由于哈希表利用数组这种特性,在哈希表中进行添加,删除,查找等操作,在不考虑哈希冲突的情况下,仅需一次定位即可完成,时间复杂度为O(1)。
比如要新增或查找某个元素,把当前元素的key值,通过哈希函数映射到数组中的某个位置,通过数组下标一次定位就可完成操作。
哈希碰撞
如果两个不同的元素通过哈希函数映射得到的实际存储地址相同,即对某个key值进行哈希运算得出的实际存储地址被其他元素占用。
如何解决?
开放定址法:发生冲突,继续寻找下一个可以存储地址;
链地址法:数组+链表,hashmap采用的此方法。
HashMap
存储的是键值对。
hashmap的整体结构如下
从结构上来讲在jdk1.8之前是用数组加链表的方式实现,jdk1.8加了红黑树。
- hashmap可以接受null值;
- hashmap的内部实现,hashmap是使用数组+链表+红黑树的形式实现的,其中数组是一个一个Node[]数组,称为hash桶数组,它上面存放的是键值对的节点。
hashmap的方法实现
HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,返回的hashCode用于找到bucket位置来储存Entry对象。
存储流程
当发生哈希冲突并且size大于阈值的时候,需要进行数组扩容,扩容时,需要新建一个长度为之前数组2倍的新的数组,然后将当前的Entry数组中的元素全部传输过去,扩容后的新数组长度为之前的2倍,所以扩容相对来说是个耗资源的操作。
参考博客:
作者: dreamcatcher-cx
出处: http://www.cnblogs.com/chengxiao/