• java的HashMap的几个问题


    HashMap处理hash冲突的几种方法

    一、 开放定址法

    Hi=(H(key) + di) MOD m i=1,2,...k(k<=m-1)其中H(key)为哈希函数;m为哈希表表长;di为增量序列。

    开放定址法根据步长不同可以分为3种:

    1)线性探查法(Linear Probing):di=1,2,3,...,m-1
      简单地说就是以当前冲突位置为起点,步长为1循环查找,直到找到一个空的位置就把元素插进去,循环完了都找不到说明容器满了。就像你去一条街上的店里吃饭,问了第一家被告知满座,然后挨着一家家去问是否有位置一样。

    2)线性补偿探测法:di=Q 下一个位置满足 Hi=(H(key) + Q) mod m i=1,2,...k(k<=m-1) ,要求 Q 与 m 是互质的,以便能探测到哈希表中的所有单元。
    继续用上面的例子,现在你不是挨着一家家去问了,拿出计算器算了一下,然后隔Q家问一次有没有位置。

    3)伪随机探测再散列:di=伪随机数序列。还是那个例子,这是完全根据心情去选一家店来问了

    缺点:

    • 这种方法建立起来的hash表当冲突多的时候数据容易堆聚在一起,这时候对查找不友好;
    • 删除结点不能简单地将被删结 点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。因此在 用开放地址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点
    • 当空间满了,还要建立一个溢出表来存多出来的元素。

    二、再哈希法

    Hi = RHi(key),i=1,2,...k
    RHi均是不同的哈希函数,即在同义词产生地址冲突时计算另一个哈希函数地址,直到不发生冲突为止。这种方法不易产生聚集,但是增加了计算时间。

    缺点:增加了计算时间。

    三、建立一个公共溢出区

    假设哈希函数的值域为[0,m-1],则设向量HashTable[0...m-1]为基本表,每个分量存放一个记录,另设立向量OverTable[0....v]为溢出表。所有关键字和基本表中关键字为同义词的记录,不管他们由哈希函数得到的哈希地址是什么,一旦发生冲突,都填入溢出表。

    简单地说就是搞个新表存冲突的元素。

    四、链地址法(拉链法)

    将所有关键字为同义词的记录存储在同一线性链表中,也就是把冲突位置的元素构造成链表。

    拉链法的优点:

    • 拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
    • 由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
    • 在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。

    拉链法的缺点:

    • 指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度

    HashMap在java1.8中为什么用红黑树?

       在jdk1.8版本后,java对HashMap做了改进,在链表长度大于8的时候,将后面的数据存在红黑树中,以加快检索速度。

     举例:HashMap的put操作:

    HashMap中数组的长度为什么是2的n次幂?

       在HashMap中采用indexFor方法返回保存该对象的位置信息:

    static int indexFor(int h,int length){
        return  h & (length - 1);
    }
    
    
    
    
    static int hash(int h){
        h ^= (h >>> 20) ^ (h >>>12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

       所以数组长度是2的n次方:

    1.  h & (table.length - 1)的到对象的保存位,2的n次幂减去1在每个位数的值都是1,全部为1进行与操作速度会大大提高;
    2. 数组长度为2的n次慕时候,不同的key值算得的index相同概率较小,减小了hash碰撞的几率,同样查询也不需要总是遍历链表,查询的效率得到了提高;



    参考:
    链接:https://www.jianshu.com/p/dff8f4641814

    链接:https://blog.csdn.net/wushiwude/article/details/75331926

  • 相关阅读:
    Vue+Element-UI+jQuery+Layer+Camera+Easing的简单应用
    Vue(vue-cli脚手架)中使用layer.js做非模态弹窗(二)
    unicable
    grep 搜索目录时,怎样排除某些目录?
    Mali Midgard架构解析
    如何从GFP确定最后申请的内存来自哪个zone?
    内存申请 GFP_KERNEL GFP_ATOMIC
    Linux内核中的page migration和compaction机制简介
    IOVA/IOMMU
    memory zone spanned/present/managed区别
  • 原文地址:https://www.cnblogs.com/Mairr/p/9094833.html
Copyright © 2020-2023  润新知