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代码之美(4)---guava之Immutable(不可变)集合
Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类 ...
- java多线程(4)---volatile关键字
volatile关键字 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的 ...
- Elasticsearch Search API
当执行一个搜索时,它将这个搜索请求广播给所有的索引分片.可以通过提供路由参数来控制要搜索哪些分片.例如,当检索tweets这个索引时,路由参数可以设置为用户名: curl -X POST " ...
- linux centos 安装Jenkins(非docker方式)
写在前面 我之前写过Asp.net Core 使用Jenkins + Dockor 实现持续集成.自动化部署(一):Jenkins安装这jenkisn的安装过程,但这篇使用的是docker的方式安装的 ...
- RabbitMQ消息队列(五)-安装amqp扩展并订阅/发布Demo(.Net Core版)
publish发布消息 新建一个Asp.Net Core控制台项目:PublishDemo 安装Nuget包 Install-Package RabbitMQ.Client 添加命名空间引用 usin ...
- Flask入门第三天
一.数据库操作 1,orm orm(object-Relation Mapping),对象-关系映射,主要实现模型对象到关系数据库数据的映射. 优点: - 只需要面向对象编程, 不需要面向数据库编写代 ...
- ASP.net core 使用UEditor.Core 实现 ueditor 上传功能
ASP.net core 使用UEditor.Core 实现 ueditor 上传功能 首先通过nuget 引用UEditor.Core,作者github:https://github.com/bai ...
- 【转载】ASP.NET中Server.MapPath方法获取网站根目录总结
在ASP.NET网站应用程序中,可以通过Server.MapPath方法来获取跟服务器有关的目录信息,如获取网站的根目录.获取当前代码文件所在的目录路径.获取当前代码所在路径的上级路径等.Server ...
- “/"应用程序中的服务器错误
运行ASP.NET MVC项目时,出现了如下错误: 在网上搜索了很久并没有找到有用的答案,后来请朋友看了一下,最后改了端口号才运行成功,错误应该是之前的端口号被占用导致的.
- C# 以管理员权限删除文件
前言 通过后台,想删除C盘下”C:\\Windows\\winsxs\\Backup“的缓存文件. 然后提示对路径“C:\\Windows\\winsxs\\Backup\\amd64_hid-use ...