HashMap

HashMap是Java中基于哈希表实现的Map接口重要子类,它使用数组+链表(JDK8及以上版本还有红黑树)存储元素,支持快速查找。HashMap是非同步、无序的,允许null键值对,但不保证元素顺序。在扩容时,HashMap会扩大为原容量的2倍,最大容量可达2^30。与Hashtable相比,HashMap不是线程安全的,不推荐在并发环境中直接使用。在需要线程安全时,推荐使用ConcurrentHashMap。
摘要由CSDN通过智能技术生成

HashMap是基于哈希表的 Map 接口的实现,是Map接口下的一个极其重要的子类。本文来看看HashMap的一些知识。



1.Hash表

1.哈希表:以数组的形式保存元素,通过哈希算法确定元素的位置,哈希算法有多种。
2.常用的哈希算法:

1.直接定址法
    直接以关键字k或者k加上某个常数(k+c)作为哈希地址,即:h(k) = k + c,这种哈希函数计算简单。当关键字基本连
续时用这种方法十分方便,若关键字不连续的话将造成内存单元大量浪费。
2.数字分析法
    提取关键字中取值比较均匀的数字作为哈希地址。它适用于关键字都已知的情况,并需要对关键字中每一位的取值进行分析。
比如有80个记录,关键字是一个8位的十进制整数:m1m2m3...m7m8,如哈希表长度为100,则哈希表地址空间为0-99。进过分析
取若干位作为哈希地址,即:h(k) = m4m5m7。
3.除留余数法
    用关键字k除以某个不大于哈希表长度m的数p,将所得余数作为哈希表地址。即:h(k) = k mod p;这种方法计算比较简单,
适用范围广,是最经常使用的一种哈希函数。这种方法的关键是选好p,使得元素集合中每一个关键字通过该函数转换后映射到
哈希表范围的任意地址上的概率相等,从而尽可能减少冲突的可能性。
4.分段叠加法
    按照哈希表地址位数将关键字分成位数相等的几部分,其中最后一部分可以比较短。然后将这几部分相加,舍弃最高进位后
的结果就是该关键字的哈希地址。分段叠加又可以分成折叠法和位移法两种。位移法是将分割后的每部分低位对齐相加;折叠法
是将奇数段正序偶数段逆序然后相加。
5.平方取中法
    如果关键字各个部分分布都不均匀的话,可以先求出它的平方值,然后按照需求取中间的几位作为哈希地址。因为平方值的
中间部分跟关键字的每一位都有相关性,所以产生随机数的概率比较高。
6.伪随机数法
    伪随机数法是指采用一个伪随机数当作哈希函数,即h(k) = random(k)。
其中最重要的是方法1和方法3。

3.哈希算法的选取原则:

    在判断性能时通常要考虑4个因素:
    1.计算哈希函数所需要的时间。
    2.关键字的长度
    3.关键字分布情况
    4.查找频率
    性能好的哈希函数能减少冲突,通常不可能完全避免冲突,所以解决冲突也是哈希表的另一个关键问题。解决冲突在创建
哈希表和查找时应该保持一致。

4.哈希冲突:两个对象的哈希值相同,但是内容不同。
5.哈希冲突的解决办法:

1.线性探查法
    发生冲突时,线性遍历后续单元直到找到空闲单元。即d[i] = (d[i-1] + 1) mod m线性探查容易产生堆积的问题。因为
若是出现了若干个同意词会堆积在第一个同义词的地址单元附近。
2.平方探查法
    发生冲突时,用平方探查法的探查序列为d[i] + 1²,d[i] + 2², d[i] + 3²...直到找到空闲单元。平方探查法是一种
比较好的处理冲突的方法,可以避免堆积问题。它的缺点是不能探查到哈希表上的所有单元,不过至少也能探查到一半单元。
3.链地址法(拉链法)
    链地址法的思想是将哈希表的每个单元作为链表的头结点,所有哈希地址为i的元素构成一个同义词链表。即发生冲突时就
把该关键字链在以该单元为头结点的链表的尾部。链地址法适用于经常插入删除的情况,
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值