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的性能影响的更多相关文章

  1. Java中hashCode()方法以及HashMap()中hash()方法

    Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...

  2. 判断Set里的元素是否重复、==、equals、hashCode方法研究-代码演示

    被测试类,没有重写hasCode()和equals()方法: package niukewang; import java.util.Objects; public class setClass { ...

  3. Day09_43_Set集合_HashSet_02(HashCode方法 与 equals方法 )

    HashSet - 向Hash表中添加元素的过程? 1. 先调用将要被存储的值key的HashCode方法得出Hash值,如果该Hash值在现有Hash表中不存在,那么直接加入元素. 2. 如果该Ha ...

  4. 详解equals()方法和hashCode()方法

    前言 Java的基类Object提供了一些方法,其中equals()方法用于判断两个对象是否相等,hashCode()方法用于计算对象的哈希码.equals()和hashCode()都不是final方 ...

  5. Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. Java 8 中 HashMap 的性能提升

    HashMap是一个高效通用的数据结构,它在每一个Java程序中都随处可见.先来介绍些基础知识.你可能也知 道,HashMap使用key的hashCode()和equals()方法来将值划分到不同的桶 ...

  7. 对Java中HashCode方法的深入思考

    前言 最近在学习 Go 语言,Go 语言中有指针对象,一个指针变量指向了一个值的内存地址.学习过 C 语言的猿友应该都知道指针的概念.Go 语言语法与 C 相近,可以说是类 C 的编程语言,所以 Go ...

  8. equals()方法和hashCode()方法

    1.equal()方法 2.hasCode()方法 2.1 Object的hashCode() 2.2 hashCode()的作用 3.String中equals()和hashCode()的实现 4. ...

  9. (转载)两种方法让HashMap线程安全

    HashMap不是线程安全的,往往在写程序时需要通过一些方法来回避.其实JDK原生的提供了2种方法让HashMap支持线程安全. 方法一:通过Collections.synchronizedMap() ...

随机推荐

  1. TP3.2框架中的字母函数解析

    C的使用方法以及注意事项 使用方法: 1.读取配置 C('参数名称')  配置参数不区分大小写,存在则设置,否则返回NULL; 因为配置参数是全局有效的,因此C方法可以在任何地方读取任何配置,即使某个 ...

  2. Steeltoe之Distributed Tracing篇

    Steeltoe里的分布式追踪功能与Spring Cloud Sleuth一样,支持在日志中记录追踪数据,或者上传到远端的服务,比如Zipkin. Logging 在Steeltoe中使用日志时需要引 ...

  3. [六]JavaIO之 ByteArrayInputStream与ByteArrayOutputStream

      功能简介   ByteArrayInputStream 和 ByteArrayOutputStream 提供了针对于字符数组 byte [] 的标准的IO操作方式     ByteArrayInp ...

  4. Django学习笔记(1)——初识Django

    一:Web框架介绍 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以快速帮你开发特定的系统. Web框架是别人已经设定好的一个web网站模板,你学习它 ...

  5. Redis应用之[限制访问频率]

      我们知道当网站的访问量突然很大的时候肯定会对服务器造成影响,甚至无法访问,如果是正常的访问那么很好说明业务量增大可以考虑系统的扩展,但是如果是搜索引擎爬虫频繁访问或是一些恶意访问,那这时候我们就应 ...

  6. Perl List::Util模块用法详解

    本文介绍Perl标准库List::Utils中的列表工具,有时候它们非常好用.比如Perl中测试列表中是否包含某个元素(某个元素是否存在于列表中)没有比较直接比较方便的功能,但使用List::Util ...

  7. VS2017安装过程中【工作负载】选择安装

    Visual Studio 2017安装和12.13.15安装过程一样的,只是17安装的时候 选择的[工作负载]不同了,小编安装17的目的是为了安装“.Net Core跨平台开发” 这个模块,当然,其 ...

  8. 【.NET Core项目实战-统一认证平台】第十章 授权篇-客户端授权

    [.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章介绍了如何使用Dapper持久化IdentityServer4(以下简称ids4)的信息,并实现了sqlserver和mysql两种 ...

  9. javascript基础修炼(11)——DOM-DIFF的实现

    目录 一. 再谈从Virtual-Dom生成真实DOM 二. DOM-Diff的目的 三. DOM-Diff的基本算法描述 四. DOM-Diff的简单实现 4.1 期望效果 4.2 DOM-Diff ...

  10. [PHP] foreach循环的引用赋值可能导致的问题

    foreach($arr as &$value)1.引用赋值符号&,是每次循环的时候,把当前元素变成地址,$value变量就是对应元素的地址,循环结束$value是一个指向最后一个元素 ...