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() ...
随机推荐
- 【Java基础】【14正则表达式&常用工具类】
14.01_常见对象(正则表达式的概述和简单使用) A:正则表达式 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则.有自己特殊的应用. 作用:比如注册邮箱,邮箱有 ...
- linux下(fdisk,gdisk,parted)三种分区工具比较
1 2种分区结构简介 MBR分区 硬盘主引导记录MBR由4个部分组成 主引导程序(偏移地址0000H--0088H),它负责从活动分区中装载,并运行系统引导程序. 出错信息数据区,偏移地址0089H- ...
- 在centos7中python3的安装注意
---恢复内容开始--- 云主机的python是2.7有些不方便,故要更换3,看到官网有3.6的包,就下载了. wget https://www.python.org/ftp/python/3.6.3 ...
- ASP.NET Core 2.1 : 十二.内置日志、使用Nlog将日志输出到文件
应用离不开日志,虽然现在使用VS有强大的调试功能,开发过程中不复杂的情况懒得输出日志了(想起print和echo的有木有),但在一些复杂的过程中以及应用日常运行中的日志还是非常有用. ASP.NET ...
- Spring源码情操陶冶#task:executor解析器
承接Spring源码情操陶冶-自定义节点的解析.线程池是jdk的一个很重要的概念,在很多的场景都会应用到,多用于处理多任务的并发处理,此处借由spring整合jdk的cocurrent包的方式来进行深 ...
- Java面试系列--java基础
Java基础总结 JAVA中的几种基本数据类型是什么,各自占用多少字节. 八大基本数据类型,byte:8位,short:16位,int:32位,long:64位,float:32位,double:64 ...
- 产品炼成记·hostingranking.cn·基于ghost的轻量技术架构整理
本篇纯粹只讲hostingranking.cn网站的技术架构,也就是怎么做到的,达到什么效果.至于它是什么,为什么要做暂且不说,另篇会分享. 技术组成 首先hostingranking.cn是基于gh ...
- ubuntu开发项目不能执行热更新
当项目开发到一定成熟度,项目基本上比较大(vue,angular,react,java,php等),在Ubuntu系统环境下,我们写了代码,但是不能想Windows一样执行热更新,这是因为Ubuntu ...
- 学JAVA第十一天,属性与方法
今天清明节假期结束第二天,昨天请了一天假去考科目二,还好考过了,O(∩_∩)O哈哈~~~~ 今天老师讲了类的属性与方法的使用 就用代码来说明吧: package pkg3;public class T ...
- java Calendar的学习分享
前言: 在我们的日常生活中,常常能看见时间.如:在我们的手机里,在一些网站上也能随处看到时间.那我们在项目的开发中,也常常涉及到时间的处理,对于我们经常会遇到和处理的问题.Java中专门为我们处理时间 ...