JAVA中的HashMap的hashcode(散列码)

**提出问题:**如何在O(1)时间查找一个值?,换句话说就是如何才能用更高效的方式去在一个容器中查找一个元素。
**分析问题:**要想在容器中以O(1)时间查找一个元素,也就是说给数据元素一个确定的索引,通过查找搜索键所对应的索引即可实现。
**引入问题:**如何实现一个索引?如何实现搜索键(key)与值(value)的对应关系?
**问题的起源:**哈希,最早提出了构造一种数据的关键字与数据元素存放位置之间的对应关系,即数学问题中的散列,因此也称散列表(存储值的数组)为哈希表。


JAVA的集合框架定义了java.util.Map接口来对映射表建模
基础概念:
散列表(哈希表): 存储值的数组;
**散列函数:**把搜索键(Key)映射到散列表的索引上的函数;
**散列码(hashcode):**搜索键转换成整数类型的散列码;
**完美散列函数:**每一种搜索键都映射到散列表的不同地方(没有什么是完美的,很难做到);
**冲突:**两个或者多个键对应到同一个散列表中的位置;
1.如何将键转换成散列表上对应的索引?
在Java中分为基本数据类型和String对象
1.1基本数据类型的键转换成散列码
***** byte,short,int,char类型的键都简单的转成成int类型,因此不同的搜索键对应不同的散列码;
***** float类型通过 Float.floatToIntBits(float key) 返回一个int的值,改值的位数(32位)和浮点数key的比特表示相同。。因此两个不同float类型的搜索键也具有不同的散列码;
***** long类型8个字节(64位)前面32位产生不同的散列码,因此简单的转向int类型不是一个好的选择。可以将64位拆分为两部分,通过异或操作将两部分结合(无进位)也称为折叠
通过int hashcode = (int) (key^key >>32) //亦或之后进行强转;
***** double类型通过
double key=0;
long bit =Double.doubleToLongBits(key);
int hashcode = (int)(bit^bit>>32);
1.2将String类对象的Key转换成散列码
解决思路:
1.2.1
可以通过对String类型的key 的求和各字符串的Unicode做散列码,但是比如"abc","cba"对应相同的散列码,将导致冲突。
1.2.2用多项式的形式获取Sting类型Key的各字符位置来产生散列码;
霍纳规则是采用最少的乘法运算策略,求多项式在x处的值,该规则为。利用该规则,可以求任意多项式的在x处的值。
在这里插入图片描述
根据霍纳规则可以写成:
在这里插入图片描述
简单的霍纳多项式计算:
在这里插入图片描述
结果会产生特别大的整数,超出了索引的范围
在这里插入图片描述
所以应该想办法去压缩该hashcode, 通常希望将一个整数压缩到0~N-1范围内(N代表散列表的长度,一般为大于2的素数)
H(hashcode) = hashcode % N;
但是在java.util.HashMap中默认初始容量必须是2的整次数幂
在这里插入图片描述
原因是N为2的整数次幂,更加合理;
h(hashcode) = hashcode % N 等价于 h(hashcode) = hashcode &(N-1) //操作与运算符,两数相与都为1结果才为1.而操作符&的运算速率比%效率更高
同时,还要保证散列码是均匀的,所以在查看源码中由补充的散列函数补充一起使用;

**额外的知识点:
Java的根Object具有hasncode方法,默认是打印一个对象的哈希地址,当重写equals()方法时,也必须重写hashcode方法,从而保证两个相等的对象返回的散列码相同。String,Integer类都重写了equals()方法,所以String,Integer的实例调用该方法,比较得是两个对象的的值是否相同(默认比较的是对象的引用)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值