hashCode()方法对HashMap的性能影响
HashMap的put()方法会比较key的hash值,key的hash值获取方式如下:
//HashMap的put方法
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
//先获取key的hash值,如果key为null则hash值为0;如果key不为null,则获取key的hashCode值赋给h,然后求出h的(h向右移16位)次方,作为key的hash值
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
/**
* Returns a hash code value for the object. This method is
* supported for the benefit of hash tables such as those provided by
* {@link java.util.HashMap}.
*/
public native int hashCode();
可以看到,最后调用的还是hashCode()方法
实现一个好的hashCode()方法,能够尽可能地减少冲突,性能就会大大提高,下面举个栗子:
创建一个对象,让它重写hashCode方法,返回固定的值1
public class TestObject {
public String name; @Override
public int hashCode() {
return 1;
} public TestObject(String name) {
this.name = name;
}
}
然后创建10000个对象存入hashMap中,并用get方法取出来,计算耗时
public class Test { public static void main(String[] args) {
HashMap<TestObject, String> hashMap = new HashMap<>();
long currentTimeMillis = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
TestObject testObject1 = new TestObject("zhangsan");
hashMap.put(testObject1, "abc");
}
for (TestObject testObject : hashMap.keySet()) {
hashMap.get(testObject);
}
System.out.println(System.currentTimeMillis() - currentTimeMillis);
} }
输出结果为:
1616
也就是一千多ms
如果不重写HashCode方法,用自己默认的hashCode方法
public class TestObject {
public String name; public TestObject(String name) {
this.name = name;
}
}
再次运行,输出结果为:
6
几毫秒左右
另外说一下,发生冲突后数据的存放问题:
当put()操作有冲突时,新的Entry依然会被安放在对应的索引下标内,并替换原有的值。同时,
为了保证旧值不丢失,会将新的Entry的next指向旧值。这便实现了在一个数组索引空间内,存放多个值项。
此时,HashMap实际上是一个链表的数组。
如果hashCode()或者hash()方法实现较差,在大量冲突产生的情况下,HashMap事实上就退化为几个链表,对HashMap的操作等价于遍历链表,此时性能很差。
hashCode()方法对HashMap的性能影响的更多相关文章
- Java中hashCode()方法以及HashMap()中hash()方法
Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...
- 判断Set里的元素是否重复、==、equals、hashCode方法研究-代码演示
被测试类,没有重写hasCode()和equals()方法: package niukewang; import java.util.Objects; public class setClass { ...
- Day09_43_Set集合_HashSet_02(HashCode方法 与 equals方法 )
HashSet - 向Hash表中添加元素的过程? 1. 先调用将要被存储的值key的HashCode方法得出Hash值,如果该Hash值在现有Hash表中不存在,那么直接加入元素. 2. 如果该Ha ...
- 详解equals()方法和hashCode()方法
前言 Java的基类Object提供了一些方法,其中equals()方法用于判断两个对象是否相等,hashCode()方法用于计算对象的哈希码.equals()和hashCode()都不是final方 ...
- Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Java 8 中 HashMap 的性能提升
HashMap是一个高效通用的数据结构,它在每一个Java程序中都随处可见.先来介绍些基础知识.你可能也知 道,HashMap使用key的hashCode()和equals()方法来将值划分到不同的桶 ...
- 对Java中HashCode方法的深入思考
前言 最近在学习 Go 语言,Go 语言中有指针对象,一个指针变量指向了一个值的内存地址.学习过 C 语言的猿友应该都知道指针的概念.Go 语言语法与 C 相近,可以说是类 C 的编程语言,所以 Go ...
- equals()方法和hashCode()方法
1.equal()方法 2.hasCode()方法 2.1 Object的hashCode() 2.2 hashCode()的作用 3.String中equals()和hashCode()的实现 4. ...
- (转载)两种方法让HashMap线程安全
HashMap不是线程安全的,往往在写程序时需要通过一些方法来回避.其实JDK原生的提供了2种方法让HashMap支持线程安全. 方法一:通过Collections.synchronizedMap() ...
随机推荐
- Python操作Redis及连接方式
前沿:随着互联网的高速发展,数据变得越来越重要,Python成为了人工智能的热门语言,而Nosql数据库已成为日常开发用品. 今天要写的是Python操作Redis Redis的安装我就不介绍了,你可 ...
- java基础(十六)----- equals()与hashCode()方法详解 —— 面试必问
本文将详解 equals()与hashCode()方法 概述 java.lang.Object类中有两个非常重要的方法: public boolean equals(Object obj) publi ...
- JDK1.8源码(三)——java.util.HashMap
什么是哈希表? 在讨论哈希表之前,我们先大概了解下其他数据结构在新增,查找等基础操作执行性能 数组:采用一段连续的存储单元来存储数据.对于指定下标的查找,时间复杂度为O(1):通过给定值进行查找, ...
- MySQL使用过程中的报错处理(持续更新)
一.数据库初始化 1.Percona的MySQL 5.6.20版本数据库初始化 初始化命令(MySQL 5.6版本不适用mysqld命令进行初始化) ./scripts/mysql_install_d ...
- 记一次Eureka启动报Failed to start bean 'eurekaAutoServiceRegistration' 。。。错误
在一次项目迁移的过程中,新导入了两个依赖,结果项目启动就报错,如下: 主要原因是:Failed to start bean 'eurekaAutoServiceRegistration'; neste ...
- kubernetes进阶之五:Replication Controller&Replica Sets&Deployments
一:Replication Controller RC是kubernetes的核心概念之一.它定义了一个期望的场景即声明某种Pod的副本数量在任意时候都要符合某个预期值. 它由以下几个部分组成: 1. ...
- 【MongoDB】使用MongoVUE看不到插入的数据
问题描述 明明在命令行中,输入mongodb的插入数据的命令,并且插入数据显示成功,却在MongoVUE可视化工具中,看不到插入的数据? mongodb使用版本为(3.4.6) mongoVUE使用版 ...
- CSS引用样式
llink和@import引入外部样式的区别 •隶属上的差别 link属于HTML标签,而@import完全是CSS提供的一种方式. •@import次数限制 @import只能引入31次css文件. ...
- Java开发笔记(五十五)关键字static的用法
前面介绍嵌套类的时候讲到了关键字static,用static修饰类,该类就变成了嵌套类.从嵌套类的用法可知,其它地方访问嵌套类之时,无需动态创建外层类的实例,直接创建嵌套类的实例就行.其实static ...
- Ubuntu16.04 安装ROS及其IDE
一. ROS的安装 1. 进入ROS官方网站 http://wiki.ros.org/ 2. Install -> ROS Kinetic Kame -> Ubuntu 3. 详情可参考所 ...