hashCode equals ==

  • 对象相等判断
    • equals和==区别
    • hashCode 与 equals(重要) ※※
      • hashCode()介绍
      • hashCode()介绍(常见的几个问题)
      • 为什么要有 hashCode(HashSet如何检查重复)(重要)
      • 对象的相等与指向他们的引用相等,两者有什么不同?
      • hashCode()与equals()的相关规定(重要)
      • 代码详讲hashCode()与equals() ==内容
    • 值传递
      • 为什么 Java 中只有值传递
      • 值传递和引用传递有什么区别

对象相等判断

equals和==区别

==

  • 基本数据类型 ==比较的是值是否相同
  • 引用数据类型 ==比较的是否 相同对象
    equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
  • 类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
  • 类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)

额外说明String中的比较

  • String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,
    而String的equals方法比较的是对象的值。
  • 当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相
    同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象

hashCode 与 equals(重要) ※※

hashCode()介绍

  • hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数
  • 散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的值。这其中就利用到了散列码!(可以快速找到所需要的对象)
  • 总结 hashCode()是一个堆内对象位置返回的一个int数值,他不是对象位置,但代表对象位置

hashCode()介绍(常见的几个问题)

  • HashSet如何检查重复
  • 两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?
  • hashCode和equals方法的关系
    面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode
    方法?”

为什么要有 hashCode(HashSet如何检查重复)(重要)

我们以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode:
当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,
如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查hashcode 相等的对象是否真的相同(equals()方法被覆盖过,则 hashCode 方法也必须被覆盖
如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。

对象的相等与指向他们的引用相等,两者有什么不同?

对象的相等 比的是内存中存放的内容是否相等 equals
引用相等 比较的是他们指向的内存地址是否相等 ==

hashCode()与equals()的相关规定(重要)

  • 如果两个对象相等,则hashcode一定也是相同的
  • 两个对象相等,对两个对象分别调用equals方法都返回true
  • 两个对象有相同的hashcode值,它们也不一定是相等的 (下面示例解答)
    因此,equals()方法被覆盖过,则 hashCode 方法也必须被覆盖,hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),否则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

代码详讲hashCode()与equals() ==内容

如下String类的hasCode()和equals()说明,先写一段代码

public class Hashcode {public static void main(String[] args) {String a = new String("0");String b = new String("0");String c = "1";String d = "1";System.out.println(a.hashCode());// 48System.out.println(b.hashCode());// 48System.out.println(a==b);       // falseSystem.out.println(a.equals(b));// trueSystem.out.println(c.hashCode());// 49System.out.println(d.hashCode());// 49System.out.println(c==d);      // trueSystem.out.println(c.equals(d));// true  }
  • 先看hasCode()的介绍,这里拿String类说明,hasCode是object中的方法,在String类中有重写,我们结合String a = new String(“0”);计算下hasCode的值
    /**用于字符存储*/private final char value[];/**缓存字符串的哈希码*/private int hash; // Default to 0public int hashCode() {int h = hash;//h值默认为0,"0"对应value.length应该为1if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {// 这一步对应的h=31*0 +'0'  字符型+数值,字符转换unicode数字,'0'编码对应48 h = 31 * h + val[i];}hash = h;}return h;}

在String类中,关于hasCode的值是一个算法(结合unicode编码),无论new多少个对象,只要值是字符串"0",hasCode值就是48,所以如果两个对象相等,则hashcode一定也是相同的

  • 再来看下equals()的说明解释String类对于equals方法覆写
    public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;// 这一步拆分循环比较每个字符串内容,不一样返回false,所以这里是内容比较while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}

String类对于equals方法覆写,循环比较每个字符串内容,不一样返回false
两个对象相等,对两个对象分别调用equals方法都返回true

  • 最后来看==的两个比较
    ①先看 == 那个输出为false的,a和b分别是new的对象,这是两个对象,hasCode值都是48,但是a == b比较输出为false,两个对象有相同的hashcode值,它们也不一定是相等的即使这两个对象指向相同的数据,equals()方法进行覆盖过,输出为true,**equals()方法被覆盖过,则 hashCode 方法也必须被覆盖,hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),否则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)**其实hasCode是一个算法,返回int类型
    ②再看第二个 == 输出为true的,c和d的hasCode值也是一样的,这里输出为true是因为,定义一个字符串"1",相当于创建了一个String对象值为"1",存放在元数据内,String对象c和d分别引用这个String对象,这里属于引用相等:比较的是他们指向的内存地址是否相等引用的同一个对象,所以相等

值传递

当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递
是值传递。Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方
法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的

为什么 Java 中只有值传递

按值调用
java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,也就是
说,方法不能修改传递给它的任何参数变量的内容
总结
Java程序设计语言对对象采用的不是引用调用,实际上,对象引用是按值传递的。
下面再总结一下Java中方法参数的使用情况:
一个方法不能修改一个基本数据类型的参数(即数值型或布尔型》
一个方法可以改变一个对象参数的状态。
一个方法不能让对象参数引用一个新的对象。

值传递和引用传递有什么区别

  • 值传递:指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互不相关了。
  • 引用传递:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)

Java基础- 对象相等判断相关推荐

  1. java基础—对象转型

    一.对象转型介绍 对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型.转型的意思是:如把float类型转成int类型,把double类 ...

  2. Java基础系列:判断空指针的三种方式

    1 简介 空指针:针对对象类型,对象在堆中分配"房子".空指针(null)的对象没有分配到"房子",所以,无法使用该对象. 使用任何的对象数据时,都要进行空指针 ...

  3. java空对象怎么判断,java怎么判断对象为空

    java怎么判断对象为空 发布时间:2020-06-10 09:34:15 来源:亿速云 阅读:116 作者:Leah java怎么判断对象为空?针对这个问题,今天小编总结这篇有关对象判断的文章,希望 ...

  4. 一天一个Java基础——对象和类

    1.在Java中你所做的全部工作就是定义类,产生那些类的对象,以及发送消息给这些对象 2.可以在类中设置两种类型的元素:字段(也被称作数据成员)和方法(也被称作成员函数) 3.字段可以是任何类型的对象 ...

  5. [Java基础]对象(反)序列化流

    对象序列化流: 代码如下: package ObjectOutputStreamPack;import java.io.Serializable;public class Student implem ...

  6. java编写奇数偶数,java基础奇数偶数判断

    class="java" name="code"> 1. 按位与运算 按位与运算符"&"是双目运算符.其功能是参与运算的两数各 ...

  7. java基础语法——条件判断与循环语句

    目录 一.流程控制语句 流程控制语句分类 二.顺序结构 顺序结构概述 顺序结构图 三.选择结构 选择结构概述 选择结构(if语句1) 选择执行图1 选择结构(if语句2) 选择执行图2 选择结构(if ...

  8. java基础算法 闰年判断

    资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个年份,判断这一年是不是闰年. 当以下情况之一满足时,这一年是闰年: 年份是4的倍数而不是100的倍数: 年份是400的倍数. ...

  9. Java基础----对象与类

    一.面向对象程序设计概述 面向对象程序设计(oop) 二.类 类(class)是构造对象模板或蓝图 由类构造(construct)对象的过程称为创建类的实例(instance) 封装是处理对象的一个重 ...

最新文章

  1. python yield 和 yield from用法总结
  2. Complete Guide to Parameter Tuning in XGBoost (with codes in Python)
  3. zabbix-server 的安装-centos7
  4. golang基础环境配置
  5. 两种方法判断有向图是否有环【DFS】【拓扑排序】
  6. 深入探讨编程到底需要知道多少数学知识
  7. php分页教程,php 如何分页 教程
  8. java 自定义对象 排序,使用自定义排序顺序对对象的ArrayList进行排序
  9. reactor p java_Java反应式框架Reactor中的Mono和Flux
  10. @requestbody和@requestparam到底什么作用
  11. 嵌入式Linux入门4:版本控制git的使用
  12. json返回的img图片被原样输出_爬取百度图片,并下载至本地
  13. centos怎么装python_centos下安装python的过程
  14. vue computed 传参_前端面试时面试官想要听到什么答案(关于一些Vue的问题)
  15. JavaScript图片跟随鼠标移动
  16. 音频采集 via Media Foundation
  17. 微信windows版本体验报告
  18. 蓝桥杯之单片机学习(三)——共阳数码管的静态显示
  19. java个十百千万位余数_1 Java第三课[流程控制]
  20. CRC碰撞概率 与CRC校验长度的理解

热门文章

  1. Solr JVM内存不足
  2. 使用python处理wps表格_python中常⽤的excel模块库
  3. Selenium IDE教程
  4. tl-wdr5620虚拟服务器,TP-Link TL-WDR5620路由器怎么设置?
  5. dwd明细粒度事实层设计
  6. 组织结构流程图模板分享 教你快速绘制流程图
  7. 宝塔php版本切换没效果_关于宝塔面板默认PHP版本及切换
  8. 将c#窗体从一个项目1移动到另外一个项目2中
  9. 数据结构:图的基础知识
  10. Java初学者入门简介