Java的Object类中有一个hashCode()方法:

public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) { return (this == obj);
}
public String toString() { return getClass().getName() + "@" +  Integer.toHexString(hashCode());
}

hashCode()是一个native方法,意味着方法的实现和硬件平台有关,默认实现和虚拟机有关,对于有些JVM,hashCode()返回的就是对象的地址,

大多时候JVM根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,并返回。

例如:HotSpot JVM中生成hash实现:hotspot/src/share/vm/runtime/synchronizer.cpp
在Java中,hashCode()方法的主要作用是为了配合基于散列的集合(HashSet、HashMap)一起正常运行。当向集合中插入对象时,
调用equals()逐个进行比较,这个方法可行却效率低下。因此,先比较hashCode再调用equals()会快很多。
下面这段代码是java.util.HashMap的中put方法的具体实现:
public V put(K key, V value) {if (key == null)return putForNullKey(value);int hash = hash(key.hashCode());int i = indexFor(hash, table.length);for (Entry<K,V> e = table[i]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}modCount++;addEntry(hash, key, value, i);return null;}

indexFor()源码如下:

static int indexFor(int h, int length) { return h & (length-1);
}

因为hashMap要求Entry数组长度必须为2的幂(hashMap默认值为16,hashTable没有这个要求,默认值为11),

所以上述代码就是取h的低4位作为Entry数组的下标。由于覆盖equals()需要覆盖hashCode(),

所以hashCode()有时并不十分完美,比如只和高位有关等等,因此需要再次hash()一下。

hash()方法在JDK1.7中如下:

static int hash(int h) {// This function ensures that hashCodes that differ only by// constant multiples at each bit position have a bounded// number of collisions (approximately 8 at default load factor).h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4);
}

这样设计保证了对象的hashCode的32位值只要有一位发生改变,整个hash()返回值就会改变,高位的变化会反应到低位里。

具体分析参考:http://www.iteye.com/topic/709945

https://www.zhihu.com/question/20733617

hash()方法在JDK1.8中如下:

static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

这样设计保证了对象的hashCode的高16位的变化能反应到低16位中,相比较而言减少了过多的位运算,是一种折中的设计。

Java中hashCode()方法以及HashMap()中hash()方法相关推荐

  1. 蔚来一面:HashMap 的 hash 方法原理是什么?看完这篇还不懂HashMap的hash原理,那我要哭了~

    Warning:这是<Java 程序员进阶之路>专栏的第 55 篇.那天,小二去蔚来面试,面试官老王一上来就问他:HashMap 的 hash 方法的原理是什么?当时就把裸面的小二给蚌埠住 ...

  2. String中的hashcode缓存以及HashMap中String作key的好处

    目录 hashcode方法源码 不可变性 缓存HashCode 线程安全 hashcode方法源码 public int hashCode() {int h = hash;if (h == 0 &am ...

  3. HashMap 中 hash 冲突的解决方法及原理分析

    我们最先衰老的不是容貌,而是不顾一切的闯劲.有时候,要敢于背上超出自己预料的包袱,真的努力后,你会发现自己要比想象的优秀很多. HashMap冲突的解决方法比较考验一个开发者解决问题的能力. 在Jav ...

  4. HashMap中的hash与rehash

    HashMap中的hash与rehash 我们知道HashMap中经常用到hash()方法. 比如:put()方法中 public V put(K key, V value){if(key==null ...

  5. HashMap 中那些精妙绝伦的设计

     点击上方关注 "终端研发部" 设为"星标",和你一起掌握更多数据库知识 一.HashMap构造器 HashMap总共给我们提供了三个构造器来创建HashMap ...

  6. 2021 Java面试题总结(更新中)

    目录 一.面试题 1.SpringMVC的流程? 2.SpringMVC怎么设定 重定向 和 转发 的? 3.SpringMVC常用的注解有哪些? 4.Equal 和 == 区别 ==运算符的使用 e ...

  7. HashMap中的红黑树

    转载自:http://blog.csdn.net/u011240877/article/details/53358305 张拭心 读完本文你将了解到: 点击查看 Java 集合框架深入理解 系列 - ...

  8. 怎么在html中去掉空白,5种方法去掉HTML中Inline-Block元素之间的空白

    5种方法去掉HTML中Inline-Block元素之间的空白 记得年轻时我在IE6上开发,绝望的希望IE6能支持display: inline-block功能. 当需要在"inline&qu ...

  9. Java数据结构和算法:HashMap的实现原理

    HashMap源码理解 Java集合之HashMap HashMap原理及实现学习总结 HashMap源码分析 HashMap原理及实现学习总结 1. HashMap概述 HashMap是基于哈希表的 ...

最新文章

  1. Jzoj4747 被粉碎的线段树
  2. android 自定义dialog 定时关闭,Android编程实现自定义Dialog的大小自动控制方法示例...
  3. python天天学怎么样-每天一遍,好好学习,天天向上(Python)
  4. c语言窗口程序 画圆,C语言画圆问题。怎么跳过画图界面直接出来了?
  5. CSS选取第n个元素 :nth-child()
  6. Android UI事件处理
  7. String、String Buffer、StringBuilder区别与比较
  8. 淘宝网的技术发展史(一)——个人网站时代
  9. 课时105.边框属性下(掌握)
  10. java表达式语言种类_Java之语言控制语句
  11. 摩根溪创始人:特斯拉资产负债表有8%是比特币
  12. 老男孩教育每日一题-2017年4月10日-find命令题目
  13. ES6语法实现数据的双向绑定
  14. CFree注册码及破解过程【转】
  15. Web前端-html页面-网易注册表单,美化及时验证效果
  16. 第一门慕课计划——在广东海洋大学推广MOOC学习
  17. 在线安装rancher2.4管理K8S集群并部署服务
  18. [多-元-智-能]理论 IQ智商 EQ情商 AQ逆商 FQ财商 HQ健商 BQ戆商 CQ创商 MQ德商 DQ胆商 MQ心商 WQ志商 SQ灵商...
  19. 数学-排列组合的理解
  20. 如何快速学习STAR-CCM+软件解决工程实际问题

热门文章

  1. pad_sequences序列填充(转载)
  2. no module named 'social_core'
  3. kaggle颅内出血比赛分析
  4. kaggle提交前预估本地cv和LB上的score是否相差很大
  5. 随机森林针对中文文本分类
  6. unicode编码查询方法
  7. leetcode刷题集:栈与队列
  8. SpringBoot+webservice
  9. 组策略管理——软件限制策略(4)
  10. 关于活动目录中DNS没有SRV记录的解决方法