美文网首页
Hash总结

Hash总结

作者: 暑水 | 来源:发表于2019-08-13 10:28 被阅读0次

HashMap

原文链接:https://www.cnblogs.com/peizhe123/p/5790252.html

  • hashmap原理:
    HashMap类有一个叫做Entry的内部类。这个Entry类包含了key-value作为实例变量。 每当往hashmap里面存放key-value对的时候,都会为它们实例化一个Entry对象,这个Entry对象就会存储在前面提到的Entry数组table中。Entry具体存在table的那个位置是 根据key的hashcode()方法计算出来的hash值(来决定)。

  • hashCode() 和equals() 方法的重要性
    Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。如果没有正确的实现这两个方法,两个不同的键可能会有相同的hash值,因此,可能会被集合认为是相等的。而且,这两个方法也用来发现重复元素。所以这两个方法的实现对HashMap的精确性和正确性是至关重要的。

  • hash冲突
    散列表要解决的一个问题就是散列值的冲突问题,通常是两种方法:链表法和开放地址法。链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位;开放地址法是通过一个探测算法,当某个槽位已经被占据的情况下继续查找下一个可以使用的槽位。java.util.HashMap采用的链表法的方式,链表是单向链表。

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

在Java中,HashMap的实现采用了(数组 + 链表 + 红黑树)的复杂结构,数组的一个元素又称作桶。

在添加元素时,会根据hash值算出元素在数组中的位置,如果该位置没有元素,则直接把元素放置在此处,如果该位置有元素了,则把元素以链表的形式放置在链表的尾部。

当一个链表的元素个数达到一定的数量(且数组的长度达到一定的长度)后,则把链表转化为红黑树,从而提高效率。

数组的查询效率为O(1),链表的查询效率是O(k),红黑树的查询效率是O(log k),k为桶中的元素个数,所以当元素数量非常多的时候,转化为红黑树能极大地提高效率。

当创建 HashMap 时,有一个默认的负载因子(load factor),其默认值为 0.75,这是时间和空间成本上一种折衷:增大负载因子可以减少 Hash 表(就是那个 Entry 数组)所占用的内存空间,但会增加查询数据的时间开销,而查询是最频繁的的操作(HashMap 的 get() 与 put() 方法都要用到查询);减小负载因子会提高数据查询的性能,但会增加 Hash 表所占用的内存空间。

Java7扩容时,遍历每个节点,并重新hash获得当前数组的位置并添加到链表中;Java8进一步做了优化,将元素的hash和旧数组的大小(大小为2次幂)做与运算,为0则表示数组位置不变,不为0则表示需要移位,新位置为原先位置+旧数组的小大(新数组大小为旧数组翻倍),并将当前链表拆分为两个链表,一个链表放到原先位置,一个链路放到新位置,效率比Java7高。额外提一点,Java的链表节点数超过8个时,会将链表转化为红黑树,当hash命中很低时,效率比Java7高很多,

HashMap基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

值得注意的是HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap。

Map map = Collections.synchronizedMap(new HashMap());

HashMapde 一些关键属性:

transient Entry[] table;//存储元素的实体数组
 
transient int size;//存放元素的个数
 
int threshold; //临界值   当实际大小超过临界值时,会进行扩容threshold = 加载因子*容量

 final float loadFactor; //加载因子
 
transient int modCount;//被修改的次数

相关文章

  • Hash总结

    HashMap 原文链接:https://www.cnblogs.com/peizhe123/p/5790252....

  • Hash算法总结

    1. Hash是什么,它的作用 先举个例子。我们每个活在世上的人,为了能够参与各种社会活动,都需要一个用于识别自己...

  • Hash算法总结

    1. Hash是什么,它的作用 先举个例子。我们每个活在世上的人,为了能够参与各种社会活动,都需要一个用于识别自己...

  • 一致性hash算法及其java实现

    目录 •目录 •背景 •分配方法 •一致性hash原理 •使用虚拟节点解决hash不均匀的问题 •总结 •Java...

  • windows hash抓取总结

    前言 最近在看ms08067出版的《内网渗透测试基础》,总结的还是挺好的。这里把windows抓取hash的一些方...

  • HashMap

    Java HashMap 标签(空格分隔): Java source-code hash-map 总结 HashT...

  • Consistent hash学习与总结

    近期在学习分布式存储相关的知识,了解和熟悉一些数据分布相关的算法,本文总结一下最近的学习成果。 本文目标 熟悉普通...

  • Golang标准库——hash

    hash hash包提供hash函数的接口。 type Hash Hash是一个被所有hash函数实现的公共接口。...

  • 散列表 - Hash Table

    「总结自《Grokking Algotithms》这本书第五章内容」 散列函数 哈希表(Hash Table),学...

  • 你真的了解HASH吗?

    什么是Hash?什么是Hash表?什么是Hash冲突? HASH   哈希(散列)是指:任意长度的输入经过hash...

网友评论

      本文标题:Hash总结

      本文链接:https://www.haomeiwen.com/subject/hwfvjctx.html