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

java的HashMap的几个问题的更多相关文章

  1. java:警告:[unchecked] 对作为普通类型 java.util.HashMap 的成员的put(K,V) 的调用未经检查

    java:警告:[unchecked] 对作为普通类型 java.util.HashMap 的成员的put(K,V) 的调用未经检查 一.问题:学习HashMap时候,我做了这样一个程序: impor ...

  2. angularJS操作键值对象(类似java的hashmap)填坑小结

    前言: 我们知道java的hashmap中使用最多的是put(...),get(...)以及remove()方法,那么在angularJS中如何创造(使用)这样一个对象呢 思路分析: 我们知道在jav ...

  3. Java学习——HashMap

    遍历 Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map. ...

  4. Java之HashMap在多线程情况下导致死循环的问题

    PS:不得不说Java编程思想这本书是真心强大.. 学习内容: 1.HashMap<K,V>在多线程的情况下出现的死循环现象   当初学Java的时候只是知道HashMap<K,V& ...

  5. Mabitis 多表查询(一)resultType=“java.util.hashMap”

    1.进行单表查询的时候,xml标签的写法如下 进行多表查询,且无确定返回类型时 xml标签写法如下: <select id="Volume" parameterType=&q ...

  6. 解决Apache CXF 不支持传递java.sql.Timestamp和java.util.HashMap类型问题

    在项目中使用Apache开源的Services Framework CXF来发布WebService,CXF能够很简洁与Spring Framework 集成在一起,在发布WebService的过程中 ...

  7. Java中HashMap遍历的两种方式

    Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...

  8. 简单分析Java的HashMap.entrySet()的实现

    关于Java的HashMap.entrySet(),文档是这样描述的:这个方法返回一个Set,这个Set是HashMap的视图,对Map的操作会在Set上反映出来,反过来也是.原文是 Returns ...

  9. java中HashMap的用法

    重点介绍HashMap.首先介绍一下什么是Map.在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.在下文中会 ...

  10. Java中HashMap,LinkedHashMap,TreeMap的区别[转]

    原文:http://blog.csdn.net/xiyuan1999/article/details/6198394 java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类 ...

随机推荐

  1. 数据预处理及sklearn方法实现

    1.标准化(中心化) 在许多机器学习执行前,需要对数据集进行标准化处理.因为很对算法假设数据的特征服从标准正态分布.所以如果不对数据标准化,那么算法的效果会很差. 例如,在学习算法的目标函数,都假设数 ...

  2. C# RangeHelper

    /// <summary> /// Range Helper /// </summary> /// <typeparam name="T">&l ...

  3. EasyPlayer RTSP播放器运行出现: Unable to load DLL 找不到指定的模块。exception from HRESULT 0x8007007E 解决方案

    最近有EasyPlayer RTSP播放器的开发者反馈,在一台新装的Windows Server 2008的操作系统上运行EasyPlayer RTSP播放器出现"Unable to loa ...

  4. 九度OJ 1195:最长&最短文本 (搜索)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3144 解决:1156 题目描述: 输入多行字符串,请按照原文本中的顺序输出其中最短和最长的字符串,如果最短和最长的字符串不止一个,请全部输 ...

  5. elasticsearch从入门到出门-05-集群之踩坑

    自己搭的集群, 设备: win10 + ubuntu 16 的虚拟机一个: 下载的版本:elasticsearch-5.2.0 win10 解压下就好了,不说了. ubuntu 上,我想说多了都是泪! ...

  6. Ubuntu中安装FTP 服务器自己踩得坑

    12点多了,擦!做个码农真不容易呀! 系统:Ubuntu16.04 安装:FTP 步骤: 1.不管有没有一上来我先卸载: sudo apt-get purge vsftpd 2.再安装:sudo ap ...

  7. [php]Maximum function nesting level of '100' reached错误

    今天在做后台一个模块的时候报出了这个错误. Maximum function nesting level of '100' reached 仔细分析之后发现是在类的初始化过程中(__construct ...

  8. C#练习委托、事件、事件处理

    控制台应用程序效果: 代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

  9. PAT 天梯赛 L2-010. 排座位 【并查集】

    题目链接 https://www.patest.cn/contests/gplt/L2-010 思路 因为 题意中 朋友的朋友 就是朋友 那么 朋友的关系 用 并查集 保存 但是 敌对关系 只有直接的 ...

  10. SQL语法结构

    目录 一.增 1.增加字段 2.新建约束 二.删 1.删除字段 2.删除约束 三.改 1.修改字段 一.增 1.增加字段: ALTER TABLE [表名] ADD [字段名] NVARCHAR () ...