hashcode(Java源码hashmap,当key的hashcode相同的时候,为什么会把value加到链表里)

2024-06-14 13:42:02 80

hashcode(Java源码hashmap,当key的hashcode相同的时候,为什么会把value加到链表里)

本文目录

Java源码hashmap,当key的hashcode相同的时候,为什么会把value加到链表里

HashMap底层是一个一维数组,数组每个元素是一个链表。当添加元素的时候,先通过hashcode定位到数组下标,再通过equals方法判断链表中是否有相同的key,如果不同就会添加到链表中,相同则覆盖value。

Jdk8中,如果链表元素超过8个,为了性能就会把链表变成红黑树来存储。

hashcode方法尽量能减少哈希冲突,性能最高。如果链表很长,性能也就比较低了。

一个对象的hashcode可以改变么

不能的,hash码是经过hash函数生成的不可逆的唯一序列,对象的内容改变了,hash码的序列内容才会改变,是一一对应的,hash码的这种特性用于数字签名等领域,防止内容的篡改。。

不同时重写equals和hashCode又会怎样

如果问到 == 和 equals 的区别,相信很多程序员同学都能脱口而出:一个是判断地址,一个是判断内容。

但是如果继续追问:“你重写过 equals 么?”,“重写 equals 方法的时候,必须重写 hashCode 方法么?”,“不同时重写equals和hashCode又会怎样?”

你还能信心满满地回答上来么?

== 与 equals

1. ==

如果比较的是两个基本数据类型,那么 == 比较的是值;如果是两个非基本数据类型的对象,那就是判断它们的内存地址是不是相同;

2. equals

  • 如果类没有覆盖 equals 方法,那么 equals 等价于 == ;
  • 如果覆盖了 equals 方法,那么就需要根据 equals 方法的逻辑来判断两个对象是否相等。

让我们看看 String 中的 equals 方法是什么样的:

我们可以看到 String 的比较,是先比较内存地址,如果两个字符串指向的地址不一样,那么再比较两个字符串的值。

正确使用 equals 方法

我们在使用 equals 方法的时候,容易发生空指针异常,所以在使用前需要判断对象是否为 null,或者用常量来调用 equals:

另外大家也可以使用 java.util.Objects 中的 equals 方法:

从这个方法的源码中可以看出,方法已经帮我们考虑到控制值的问题了,所以可以放心使用。

覆盖 equals 方法的准则

  • 自反性:对于任何非空引用值 A,A.equals(A) 返回 true。
  • 对称性:对于任何非空引用值 A 和 B,A.equals(B) 和 B.equals(A) 的结果相同。
  • 传递性:对于任何非空引用值 A、B 和 C,如果 A.equals(B) 返回 true, A.equals(C) 返回 true,那么 B.equals(C) 也是 true。
  • 一致性:对于任何非空引用值 A 和 B,每一次调用 x.equals(y) 的结果是相同的。
  • 非空性:对于任何非空引用值 A,A.equals(null) 应返回 false。

equals() 与 hashCode()

hashCode() 方法是获取 hash 码(哈希码、散列码),我们可以把它看做返回一个 int 整数;hash 码的作用是确定对象在散列结构中的位置。

hashCode() 方法存在于 Object 类中,代表 Java 中的任何类都会有 hashCode() 方法,那么任何场景下 hashCode() 都会产生作用么?其实并不是!

如果对象会被放入散列结构中使用,那么 hashCode() 就会起作用。

比如,当我们要向 HashMap 中放入一组 key-value 的时候,那么 HashMap 会先根据 key 对象的 hashCode 值判断存入的位置,如果 key 存入的位置上已经有了一个元素,再根据 equals() 方法判断两个元素是否相等;如果确认相等,那么会覆盖原来的 key-value 。

    这时候,equals() 与 hashCode() 就是有关系的:

    • 两个对象 equals() 返回 true 的时候,那它们的 hashCode() 值需要相等;
    • 如果两个对象的 hashCode() 值相等,那它们 equals() 不一定是 true;(哈希冲突)
    • 所以在这种情况下,如果要判断两个对象是否相等,除了要覆盖 equals() ,也要覆盖 hashCode(),否则就会发生意料之外的问题。

    当然,如果对象不会放入散列表中使用,那么 equals() 与 hashCode() 其实也没啥关系。

    我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注;关注我后,可私信发送数字【1】,获取学习资料。

    equals和hashcode的区别,hashcode的作用


    equals():反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值。
    hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数。根类Object的hashCode()方法的计算依赖于对象实例的D(内存地址),故每个Object对象的hashCode都是唯一的;当然,当对象所对应的类重写了hashCode()方法时,结果就截然不同了。
      之所以有hashCode方法,是因为在批量的对象比较中,hashCode要比equals来得快,很多集合都用到了hashCode,比如HashTable。

      两个obj,如果equals()相等,hashCode()一定相等。
      两个obj,如果hashCode()相等,equals()不一定相等(Hash散列值有冲突的情况,虽然概率很低)。
    所以:
      可以考虑在集合中,判断两个对象是否相等的规则是:
        第一步,如果hashCode()相等,则查看第二步,否则不相等;
        第二步,查看equals()是否相等,如果相等,则两obj相等,否则还是不相等。

    1、首先equals()和hashcode()这两个方法都是从object类中继承过来的。
      equals()是对两个对象的地址值进行的比较(即比较引用是否相同)。
      hashCode()是一个本地方法,它的实现是根据本地机器相关的。
    2、Java语言对equals()的要求如下,这些要求是必须遵循的:
      A 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
      B 反射性:x.equals(x)必须返回是“true”。
      C 类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
      D 一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。
      任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。
    3、equals()相等的两个对象,hashcode()一定相等;
      反过来:hashcode()不等,一定能推出equals()也不等;
      hashcode()相等,equals()可能相等,也可能不等。

    equals和hashcode谁的效率更高为什么谢谢解答


    其实不能说谁比谁高,是hashcode+equals 效率最高
    比如在hashset中,已经有1000个数据
    如果只用equals,插入第1001个数据时,需要依次和前1000个比
    如果用hashcode,可将前面数据的范围缩小(不同对象的hashcode可能相等),这样如果hashcode如果不同,直接false,相同时调用equals方法进一步确认

    equals和hashcode的区别 知乎


    Student类没有覆盖equals方法,stu1调用equals方法实际上调用的是Object的equals方法。所以采用对象内存地址是否相等来判断对象是否相等。因为是两个新对象所以对象的内存地址不相等,所以stu1.equals(stu2) 是false。

    Java中equals和 hashcode的用法


    hashcode 一般用来表示对象的唯一性。比如你在使用 hashset的时候,hashset是一个集合,而集合中的元素必须是唯一的,所以你向hashset中添加对象时,必须确保每个对象的hashcode是不同的。
    equals 的一般实现是通过比较对象的hashcode完成的,但这不是绝对,也可以有其它的实现方式,只要你认为两个对象的某属性相等那么对象就相等也可以。
    举个例子:
    hashcode就如每个学生在学校的学号,在一个学校中,每个学生的学号是唯一的。学号作为一个学生的唯一性标识,在一个学校内是不可重复的。因此,可以通过看两个学号是否相同还判断这两个学号是不是说的同一个学生,这就相当于equals的比较。而除了学号,我们还可以通过一个人的身份证号码来判断,甚至,在一定的范围内,比如在一个宿舍内,你可以通过别人给你形容一个人的高矮胖瘦等而知道别人说的是谁,这就相当于是equals的其它实现方式。

    hashcode和equals,怎么理解这段话,最好举例


    两个非基本类型变量进行比较时,先比较两个对象的hashcode,如果不一致就认为是不相等的,直接返回结果,如果相等会接着调用equals方法进行判断,如果你需要自定义比较规则,那么就需要重写hashcode和equals方法,比如有一个类User,有一个属性name,我们认为name相等那么两个对象就相等,这种情况就需要重写equals和hashcode方法:

    如果不重写就会调用Object的hashcode和equals方法,原理如下:

    public class User {
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public int hashCode() {
            // 返回的是对象的内存地址
            return super.hashCode();
        }
        @Override
        public boolean equals(Object obj) {
            // 可查看源码发现调用的是(this == obj),说明比较的还是内存地址
            return super.equals(obj);
        }
    }

    要实现上面的需求就需要重写hashcode()和equals():

    public class User {
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public int hashCode() {
            return name.hashCode();
        }
        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (obj instanceof User) {
                return name.equals(((User) obj).getName());
            }
            return false;
        }
    }

    如果我们只是重写了equals而没有重写hashcode,那么两个对象比较时

    User user1 = new User();
    user1.setName(“lily“);
    User user2 = new User();
    user2.setName(“lily“);
    boolean b = user1.equals(user2);

    由于user1和user2是两个对象,所以user1和user2的hashcode肯定是不相等的,那么会直接返回false,不会进入equals方法比较,就不会达到预期的需求。


    java里equals和hashcode之间什么关系


    这个从头说起:
    在JAVA中利用“==“比较变量时,系统使用变量在“栈“中所存的值作为比较的依据。
    基本数据类型在“栈“中存的是其内容值,
    对象类型在“栈“中存的是地址,这些地址指向“堆“中的对象。
    java.lang包中的Object类有public boolean
    equals(Object obj)方法,它比较两个对象是否相等。
    其它对象的equals方法仅当被比较的两个引用指向的对象内容相同时,对象的equals()方法返回true。
    Hash散列算法,先获取key的hashCode值,通过hash算法确定将要存储的空间(bucket)。同理,获取key的hashCode值,通过hash算法确定要检索的空间。调用 equals方法依次和bucket中的Key比较。
    key的hashCode()方法的返回值对HashMap存储元素时起着很重要的作用。hashCode()是在Object中定义的,而Object的equals方法等同于==,因此应妥善重写该方法。
    重写hashCode方法应注意:与equals方法的一致性,即两个对象equals方法比较结果为true,则hashCode方法返回值应相同。hashCode返回的数值应符合hash算法的要求。
    对于一个类如果重写了其equals方法,则必须重新hashCode方法,否则在应用hashmap时会出现各种错误。
    在对象没有改变的情况下,多次调用hashCode方法返回值应该是相同数字。

    hashcode(Java源码hashmap,当key的hashcode相同的时候,为什么会把value加到链表里)

    本文编辑:admin
    : hashcode,de,

    更多文章:


    channel into(channelinto造句)

    channel into(channelinto造句)

    本文目录channelinto造句channel是什么意思Simultaneous Outflow of Fresh Water and Inflow of Sea Water in a Coastal Springchannel什么意思c

    2024年5月12日 14:20

    asp代码问题?固铂asp-205/55r16单导向汽车轮胎94v怎么样

    asp代码问题?固铂asp-205/55r16单导向汽车轮胎94v怎么样

    本篇文章给大家谈谈asp55,以及asp代码问题对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。本文目录asp代码问题固铂asp-205/55r16

    2024年6月28日 05:30

    登录页面设计代码(asp用户登陆界面代码)

    登录页面设计代码(asp用户登陆界面代码)

    大家好,登录页面设计代码相信很多的网友都不是很明白,包括asp用户登陆界面代码也是一样,不过没有关系,接下来就来为大家分享关于登录页面设计代码和asp用户登陆界面代码的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我们开始吧!本文目

    2024年7月12日 17:59

    navigator是什么牌子(“Navigator”是什么手机的牌子)

    navigator是什么牌子(“Navigator”是什么手机的牌子)

    本文目录“Navigator”是什么手机的牌子谁知道这是什么汽车标志就是林肯标志倒过来那样川崎羽毛球拍NAVIGATOR3500i是哪牌子性能好吗,求帮助啊“Navigator”是什么手机的牌子navigator是在JavaScript中的

    2024年6月27日 00:32

    termux下安装所有渗透工具(【termux】手把手教你在Android上使用termux终端)

    termux下安装所有渗透工具(【termux】手把手教你在Android上使用termux终端)

    本文目录【termux】手把手教你在Android上使用termux终端termux安装torchtermux 安装aksharetermux安装ndktermux安装第三方库的默认安装路径【termux】手把手教你在Android上使用t

    2024年7月23日 02:54

    网站源码加密破解工具(高分求asp源码加密工具,加密源码下conn文件里面有数据库路径混浠加密都可以,能被破解也没关系)

    网站源码加密破解工具(高分求asp源码加密工具,加密源码下conn文件里面有数据库路径混浠加密都可以,能被破解也没关系)

    本文目录高分求asp源码加密工具,加密源码下conn文件里面有数据库路径混浠加密都可以,能被破解也没关系我从网上下来的php源码,所有的php文件都被加密了,有没有什么软件可以批量破解呢有什么好用一点的源代码加密软件推荐c语言高手请进 如何

    2024年7月15日 23:47

    注册表编辑器(windows7中,怎样打开注册表编辑器)

    注册表编辑器(windows7中,怎样打开注册表编辑器)

    本文目录windows7中,怎样打开注册表编辑器怎么打开注册表及编辑 win7注册表编辑器怎么打开怎么打开注册表 注册表编辑器怎么打开win10注册表编辑器怎么打开注册表编辑器关闭了如何开启如何打开注册表编辑器如何打开windows注册表编

    2023年7月6日 17:00

    zblog源码下载((有关zblog) asp源码的问题,如何将以下源码写入c_custom.asp而不错)

    zblog源码下载((有关zblog) asp源码的问题,如何将以下源码写入c_custom.asp而不错)

    本文目录(有关zblog) asp源码的问题,如何将以下源码写入c_custom.asp而不错zblog安装教程_请问谁有zblog安装教程网络错误500 zblog(有关zblog) asp源码的问题,如何将以下源码写入c_custom.

    2024年7月24日 01:14

    易语言外网聊天室(易语言外网聊天室怎么整)

    易语言外网聊天室(易语言外网聊天室怎么整)

    大家好,关于易语言外网聊天室很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于易语言外网聊天室怎么整的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!本文目录易语言

    2024年7月23日 18:20

    sqlserver存储过程面试题(求:存储过程面试题!)

    sqlserver存储过程面试题(求:存储过程面试题!)

    本文目录求:存储过程面试题!关于SQLSERVER存储过程的问题,求解SQL面试题,谢谢,麻烦了数据库存储过程有哪些,面试题关于SQLSERVER的存储过程的几个题目..求解~!~~一道面试题 :sql server 2000有哪些数据库系

    2024年7月1日 22:46

    transformers读音(变形金刚用英文怎么说带音标的)

    transformers读音(变形金刚用英文怎么说带音标的)

    本文目录变形金刚用英文怎么说带音标的变形金刚的大写拼音变形金刚的英文怎样拼transformers是什么车变形的拼音变形金刚用英文怎么说带音标的transformerstransformers 这个直接读出来没问题吧 用啥音标啊变形金刚的大

    2024年7月21日 18:09

    测试工程师招聘(有谁知道关于珠海伟创力公司的招聘信息)

    测试工程师招聘(有谁知道关于珠海伟创力公司的招聘信息)

    本文目录有谁知道关于珠海伟创力公司的招聘信息做软件测试工资高吗入门难吗广联达(一个工程软件开发公司)招得是什么测试工程师北大青鸟自己就是培训软件测试工程师的 为什么还要招有谁知道关于珠海伟创力公司的招聘信息在珠海一定要看这个网站:本公司现场

    2024年7月2日 04:26

    yarn安装失败(ubuntu怎么安装hadoop yarn)

    yarn安装失败(ubuntu怎么安装hadoop yarn)

    本文目录ubuntu怎么安装hadoop yarnhadoop安装问题yarn npm包安装 为什么需要超级管理员yarn install 为什么总失败yarn是如何解决高可用问题的请教yarn.nodemanager.local-dirs

    2023年7月23日 22:40

    编程是在电脑哪里操作(c语言在电脑的哪里编程)

    编程是在电脑哪里操作(c语言在电脑的哪里编程)

    大家好,今天小编来为大家解答以下的问题,关于编程是在电脑哪里操作,c语言在电脑的哪里编程这个很多人还不知道,现在让我们一起来看看吧!本文目录c语言在电脑的哪里编程电脑编程在哪里进行电脑上怎么编程电脑编程是在哪上面编写,怎么编在电脑上怎么编程

    2024年9月10日 12:15

    experiments(esperiment是什么意思)

    experiments(esperiment是什么意思)

    本文目录esperiment是什么意思experiment是什么意思experiment的意思esperiment是什么意思experimentn.尝试; 实验,试验; vi.尝试; 做实验,进行试验; 第三人称单数:experiments

    2024年7月24日 03:09

    c语言中括号的优先级(c语言逻辑运算符,关系运算符,算术运算符,园括号的优先级是怎么样的)

    c语言中括号的优先级(c语言逻辑运算符,关系运算符,算术运算符,园括号的优先级是怎么样的)

    大家好,c语言中括号的优先级相信很多的网友都不是很明白,包括c语言逻辑运算符,关系运算符,算术运算符,园括号的优先级是怎么样的也是一样,不过没有关系,接下来就来为大家分享关于c语言中括号的优先级和c语言逻辑运算符,关系运算符,算术运算符,园

    2024年8月7日 22:45

    穿梭时空的侠客笔趣阁(你相信能穿越时空吗)

    穿梭时空的侠客笔趣阁(你相信能穿越时空吗)

    本文目录你相信能穿越时空吗透明人、瞬移、时间暂停、永生、穿越时空,如果你可以拥有其中任意一种特异功能,你会如何选择有什么好看的穿越电视剧或者电影2020假如你穿越到楚汉战争期间成了项羽,你准备怎么做,能打败刘邦吗你相信能穿越时空吗每天在梦里

    2024年7月4日 23:28

    svn的使用的全部流程(jenkins+svn,详细的工作流程是怎样的)

    svn的使用的全部流程(jenkins+svn,详细的工作流程是怎样的)

    本文目录jenkins+svn,详细的工作流程是怎样的svn 已经提交代码,要想撤回提交该怎么操作SVN的操作说明以及备份策略jenkins+svn,详细的工作流程是怎样的安装插件后,进入系统设置页面,配置如下:官网上安全域设置为Servl

    2024年7月23日 01:58

    fedora和centos(怎样在RHEL,CentOS和Fedora上安装Git及设置Git账号)

    fedora和centos(怎样在RHEL,CentOS和Fedora上安装Git及设置Git账号)

    本文目录怎样在RHEL,CentOS和Fedora上安装Git及设置Git账号如何在Fedora或CentOS上使用Samba共享怎样在RHEL,CentOS和Fedora上安装Git及设置Git账号一、使用包管理器安装GitGit已经被所

    2024年7月22日 23:53

    在jdk中运行java程序(怎么用JDK打开JAVA)

    在jdk中运行java程序(怎么用JDK打开JAVA)

    大家好,在jdk中运行java程序相信很多的网友都不是很明白,包括怎么用JDK打开JAVA也是一样,不过没有关系,接下来就来为大家分享关于在jdk中运行java程序和怎么用JDK打开JAVA的一些知识点,大家可以关注收藏,免得下次来找不到哦

    2024年8月23日 07:30

    近期文章

    本站热文

    iphone vpn设置(ios设置vpn快捷开关)
    2024-07-22 15:01:12 浏览:2334
    windows12正式版下载(操作系统Windows Server 2012 R2,在哪能下载到,公司用的)
    2024-07-20 17:26:53 浏览:1731
    java安装教程(win10如何安装JAVA)
    2024-07-19 19:55:49 浏览:1156
    client mfc application未响应(每次进cf就提示client MFC Application未响应该怎么办啊!急急急)
    2024-07-20 11:15:58 浏览:1152
    标签列表

    热门搜索