对java的Hash方法的一些分析总结
来源:互联网 发布:烟台华商网络怎么样 编辑:程序博客网 时间:2024/04/30 05:22
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">本文大部分转自 http://www.cnblogs.com/tonyluis/p/5671873.html</span></span>
HashCode()方法是在java的Object类中定义的。
<span style="font-size:18px;">public native int hashCode(); </span>从定义可以看出,hashCode()是一个本地方法(本地方法即不是用java的代码写的,是JVM调用其他的代码,如C/C++等),所以这个方法的实现不唯一,对于一些JVM,hashCode()返回的就是对象的地址,大多时候JVM根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,并返回。
HashMap中的put()方法如下:
<span style="font-size:18px;">public V put(K key, V value) {</span>
<span style="font-size:18px;"> if (key == null)</span>
<span style="font-size:18px;"> return putForNullKey(value);</span>
<span style="font-size:18px;"> int hash = hash(key.hashCode()); //求hashcode,但是hashcode过大,不能均匀散列,所以需要hash一下</span>
<span style="font-size:18px;"> int i = indexFor(hash, table.length);//table是一个数组,存储的对那是Entry,table.length默认为16,即4位,这里取后四位,作为关键字</span>
<span style="font-size:18px;"> for (Entry<K,V> e = table[i]; e != null; e = e.next) {</span>
<span style="font-size:18px;"> Object k;</span>
<span style="font-size:18px;"> if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {</span>
<span style="font-size:18px;"> V oldValue = e.value;</span>
<span style="font-size:18px;"> e.value = value;</span>
<span style="font-size:18px;"> e.recordAccess(this);</span>
<span style="font-size:18px;"> return oldValue;</span>
<span style="font-size:18px;"> }</span>
<span style="font-size:18px;"> }</span>
<span style="font-size:18px;"> modCount++;</span>
<span style="font-size:18px;"> addEntry(hash, key, value, i);</span>
<span style="font-size:18px;"> return null;</span>
<span style="font-size:18px;"> }</span>其中,indexFor函数为
<span style="font-size:18px;">static int indexFor(int h, int length) { //取低位为table中的索引</span>
<span style="font-size:18px;"> return h & (length - 1);</span>
<span style="font-size:18px;">}</span>
因为hashMap要求Entry数组长度必须为2的幂(hashMap默认值为16,hashTable没有这个要求,默认值为11),所以上述代码就是取h的低4位作为Entry数组的下标。由于覆盖equals()需要覆盖hashCode(),所以hashCode()有时并不十分完美,比如只和高位有关等等,因此需要再次hash()一下。
JDK1.8中的hash()方法如下:
<span style="font-size:18px;">static final int hash(Object key) {</span>
<span style="font-size:18px;">int h;</span>
<span style="font-size:18px;">return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);//>>>指的是无符号右移,高16位于低16位做异或</span>
<span style="font-size:18px;">}</span>hash函数被称为扰动函数,右移16位,正好保证高半区和低半区做异或,从而混合了原来的哈希码的高位和低位,从而加大了低位的随机性,并且混合后,低位也包含了高位的信息,高位信息被变相保留下来,能够有效减小碰撞的次数。
0 0
- 对java的Hash方法的一些分析总结
- Java对数据库的调用一些常用方法总结
- 对java中Map的一些分析
- 对Java异常分析的一些见解
- 对Hash表的一些见解
- Java HashMap中hash方法的背景及分析
- 对java静态方法的一些认识
- Java中方法参数的一些总结
- 对一些方法单词写法的小总结
- 分析的一些方法
- 对Zookeeper的一些分析
- 对zookeeper的一些分析
- 对java多线程的线程安全性的一些总结
- 对存储器的一些总结
- 对js的一些总结
- 对js的一些总结
- 对redis的一些总结
- 说说对java nio的一些个人总结
- Gson 优雅实现多个枚举的自定义(反)序列化过程
- bzoj 4254 树形dp
- Sequelize和MySQL对照 【翻译】
- 题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树
- 23、H5新增js属性之本地存储
- 对java的Hash方法的一些分析总结
- WebDriver参考资料
- 根据前序遍历中序遍历求二叉树
- VM12中CentOS7以NAT的方式连接网络
- CSS之visibility和display的差别
- Linux下给进程重命名
- NAT概述
- 《从零开始学Swift》学习笔记(Day 16)——字典集合
- Libevent源码分析-----Libevent时间管理