HashMap的学习笔记

来源:互联网 发布:js对象的tostring方法 编辑:程序博客网 时间:2024/06/07 05:04

  HashMap的存储结构可以理解成数组+链表的结构,但是也不完全这样理解,因为数组查找元素的时候,需要进行遍历,严格来说,数组是一种顺序查找,当数组进行查找的时候,第一个元素找到的时间肯定比最后一个元素找到的时间短。而HashMap不同,因为存在一个Key,这个Key很关键,有了它就可以通过Hash函数找到散列的地址,在找到散列地址下的值,所以查找方式和数组不同。再接着理解链表的结构,Hash函数在计算散列值(也就是散列地址)的时候,会出现散列值相同的情况(碰撞),这个时候就会出现存储在同一个散列地址下的元素,这个解决办法就是通过链表的形式来进行存储多个同散列地址下的元素。

<分割线----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------分割线>

  但是HashMap的精华在于,散列值和索引值的求取。

 static int hash(int h) {            h ^= (h >>> 20) ^ (h >>> 12);            return h ^ (h >>> 7) ^ (h >>> 4);        }
这是JDK1.7的Hash函数,利用Hash函数的若干次位运算,将HashCode变的松散,这样得到的Hash值可以达到充分的散列均匀。

 static int hash(object key) {            int h;            return (key == null)?0:(h = key.hashCode())^(h>>>16));        }
这是JDK1.8的Hash函数,对1.7进行了优化,但是本质没有变化。



对索引值的求取,HashMap默认table(上面所说的类似数组的结构)的长度是16,在通过扰乱后的Hash值进行索引值的计算,也就是table的散列地址

static int indexFor(int h, int length) {        return h & (length-1);     }
这里需要说明的是length就是我们的table的长度,h就是我们扰乱后的Hash值,对正常来说,我们将Hash值与长度进行取模,就OK了,但是取余非常慢,我们还有更高效的相与&,进行位相与比取模要快上许多。到这里,还需要了解的是length最好是超过HashMap容量最小2的n次幂,至于为什么要进行减1,那是因为length是偶数的话,进行相与的时候,偶数二进制最低位为0这样会导致table【0】上会散列很多值,而且会使空间很浪费,减1后,奇数二进制最低为1,相与的时候,就会均匀分布。

另外,如果内存足够大,可以考虑使用大的length,这样可以使散列的更加松散,碰撞的几率更加低,get的速度就会更加快,但是会使迭代器的速度变慢,所以在使用的时候预估一下容量是非常有必要的。

<分割线----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------分割线>

还有一点,HashMap是线程不安全的,线程安全可以使用HashTable,那么HashMap线程不安全怎么体现?

如果我有两个线程同时put那么刚好碰撞到一起,那么对出现的覆盖的情况,有个put的数据会被覆盖丢失,当两个线程同时对HashMap进行扩容,在写入新的数据在扩容后的HashMap里面的时候,就会其他线程就会丢失数据。


以上就是我学习HashMap的心得,以后有新的会继续补充。。。

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

2017/9/25  补充说明:HashMap在多线程下不安全,因为其中put方法会很容易发生死循环,具体信息学习笔记重HashMap死循环连接。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 空调滴水管断了怎么办 地漏下水管断了怎么办 脸上长白色糠疹怎么办 腋下长白色的毛怎么办 饥荒电羊死光了怎么办 6s储存空间虚满怎么办 大胸下垂穿婚纱怎么办 美团签约成功后怎么办 拍婚纱照笑不出来怎么办 长得丑拍婚纱照怎么办 失恋了怎么办才能最快走出来 眼镜大了往下掉怎么办 眼镜带着往下掉怎么办 眼镜腿松了怎么办妙招 眼镜框大了总掉怎么办 吃不下饭恶心想吐怎么办 买到苹果翻新机怎么办 欠装修款不给怎么办 老板欠工资跑了怎么办 挖机老板欠工资怎么办 欠工程款耍赖不给怎么办 辞工后不给工资怎么办 工伤仲裁后不给怎么办 离职后不给工资怎么办 离职了不发工资怎么办 饭店欠工资不给怎么办 单位欠工资不给怎么办 离职后工资不发怎么办 暑假工不给工资怎么办 暑假工工资不发怎么办 个人欠钱2万不还怎么办 快递发错地址了怎么办 香烟被快递扣了怎么办 买st股票退市了怎么办 av淘宝看不了了,怎么办 厨房通水道堵了怎么办 皮鞋大了不跟脚怎么办 敞口皮鞋穿大了怎么办 穿皮鞋老掉跟怎么办 皮鞋鞋垫不粘了怎么办 上海拍好车牌后怎么办