JAVA: equals 思考

ADS 使用调整器动态调参教程(Tuning) ADS动态调参教程 阅读详情

本编博文,我想分析回顾下 Java equals方法的相关内容,并由此对散列和内存分配进行几点总结与思考,防止自己以后再犯低级错误。特此铭记,共勉。


1. == 比较

== 永远是用来比较内存地址的

网上常见的表达形式为:”==” 用于比较引用和比较基本数据类型时具有不同的功能:

  • 基本类型:
    • 如果两个变量的值相等则返回 true;
  • 引用:
    • 如果两个引用指向内存中的同一个对象,也就是引用的值(内存地址)相等,则返回true;

这种说话不能说错,但是容易给我们这些新手造成学习上的迷惑,其实基本类型实际上还是在比较地址!

  • 基本类型及其包装类,Java 中只有8中基本的数据类型分别为:
  • byte (Byte);
  • short (Short);
  • int (Integer);
  • long (Long);
  • float (Float);
  • double (Double);
  • char (Character);
  • boolean (Boolean).
    - 注意String 不是基本类型;

要弄清上面的问题我们需要理解或者说了解一下几方面的内容:

  • 堆、栈、常量池问题(对于JVM内存的具体分析和反编译来看内存的分配过程,我目前彻底理解还做不到,等我学到了回头补充)

  • 基本类型变量在栈中是怎么分配与共享的;

  • String 类型变量和基本类型的包装类型变量在不使用new时,在常量池和栈中是怎么分配的,

  • 常量池技术

在此大致总结如下,

  • 栈:存放基本类型的数据和对象的引用, 这些基本类型的变量的值和基本类型引用变量都会在栈中,其次由 new 在堆中生成的对象的引用和实现常量池的 String 和一些基本类型包装类的引用都会存在栈中;并且栈中的引用变量存的都是相应内容的所在的内存地址值;并且局部变量的数据也存放在栈中;

  • 堆:存放用new产生的数据和没有实现或者不满足常量池技术条件的基本类型包装类;

  • String类型和Java的8种基本类型包装器(Byte, Short, Integer, Long, Character, Boolean, Float, Double), 除Float和Double以外, 其它六种都实现了常量池, 但是它们只在 [-128, 127] 时才使用常量池。而如果大于127 或小于-128 则不会使用常量池所以会直接在堆内存中创建对象。

    具体分析请参考JAVA: Java 堆 栈 常量池


2 equals比较

public boolean equals(Object obj)

其比较规则为:当参数obj引用的对象与当前对象为同一个对象时,就返回true,否则返回false. 由此可见,equals()方法的本意为确定两个对象的引用是否相同。

JDK类中有一些类覆盖了oject类的equals()方法,
比较规则为:如果两个对象的类型一致,并且内容一致,则返回true,这些类有:
java.io.file, java.time.LocalDate, java.lang.string, 包装类(Integer,Double等)等;

String str="hello";
String str2 = new String ("hello");
String str3 = new String (str);
System.out.println(str2==str3);//false
System.out.println(str2.equals(str3));//true

主要: String 类重写了equals方法,只有两个对象的内容相等就返回true;

    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;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
Integer i1 = new Integer(300);
Integer i2 = new Integer(300);
System.out.println(i1==i2);//false
System.out.println(i1.equals(i2));//true        

基本类型的包装类也重写了 hashcode() 和equals 方法;

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
重写equals方法必须重写hashCode方法:

当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。

    public boolean equals(Object obj) {

        if (this == obj) {
            return true;
        }

        if (obj == null) {
            return false;
        }

        if (this.getClass() != obj.getClass()) {
            return false;
        }

        People p = (People)obj;
        return this.name.equals(p.name) && this.age == p.age;
    }
    public int hashCode() {

       // TODO Auto-generated method stub
        return name.hashCode();

    }

最后引入一段写的挺好的开场白:浅谈java中的hashCode方法
对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode。在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。

  考虑一种情况,当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?(注意:集合中不允许重复的元素存在)

  也许大多数人都会想到调用equals方法来逐个进行比较,这个方法确实可行。但是如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。此时hashCode方法的作用就体现出来了,当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。

别再买模块了!手把手教你用FT232RL-REEL芯片,从零设计一个USB转串口电路板 本文详细介绍了如何使用FT232RL-REEL芯片从零设计USB转串口电路板,涵盖核心器件选型、原理图设计、PCB布局布线及焊接调试等关键步骤。通过实战案例和性能对比,展示自制电路板在成本、性能和可靠性上的优势,特别适合硬件爱好者和工程师参考。 阅读详情

相关推荐

对数周期天线hfss建模_Ansoft HFSS 在设计对数周期天线时的仿真方法-HFSS教程

AnsoftHFSS在设计对数周期天线时的仿真方法文章来源: ANSYS 2011中国用户大会优秀论文 录入: mweda.com 点击数:【摘要】 本文通过 ANSOFT HFSS 设计了一个对数周期天线,在仿真分析时,发现随着求解频率的不同,天线的求解结果差别较大,求解误差较大。通过在 HFSS 中尝试不同的求解设置方法, 最终通过将天线模型剖分网格最大长度限定在 1/50λ的...

weixin_42186728的博客 2096

说说JAVA当中的equals

equals这个属于Object类的方法,几乎每天都在用,可是看着它,却是既熟悉,又陌生。 先来看看Object中的equals中写了什么: public boolean equals(Object obj) { return (this == obj); } 恩...似乎没有什么用,只是把当前对象的引用与传入的obj进行对比,于是,就会出现这么样的一个情况: Stri...

最后一个NPE 358

GOM Correlate拉伸试验后处理操作

本文描述了使用GOM Software 2022对拉伸试样进行后处理的操作,包括设置检测点、引伸计、输出应变数据到表格、输出报告为视频等

qq_45008924的博客 4661

equals的效率_《effective java》必学目录:快速提升编码工作效率,释放更多时间去思考方案架构设计...

根据《effective java》第2版 总结的一些提升编程效率的工作方法未完待续...持续每日更新中考虑用静态工厂方法代替构造器 遇到多个构造器参数时要考虑用构建器(builder) 用私有构造器或者枚举类型强化Singleton属性通过私有构造器强化不可实例化的能力避免创建不必要的对象 消除过期的对象引用避免使用终结方法(finalizer)覆盖equals时请遵守通用约定覆盖equals...

weixin_39966020的博客 72

Rockchip RK3568实战:手把手教你调试I2S音频驱动(附ALSA设备树配置详解)

本文提供Rockchip RK3568平台I2S音频驱动的实战调试指南。详细解析了从硬件连接到软件配置的全过程,重点涵盖ALSA驱动框架下的设备树配置、时钟计算、DMA参数设置以及常见问题(如无声、爆音)的排查与解决方法,帮助开发者快速定位并解决音频驱动难题。

weixin_28358083的博客 495

Mumax3代码模板:从基础设置到材料参数优化

本文提供了一份详尽的Mumax3微磁学模拟代码模板,从基础网格设置、边界条件到核心材料参数(如钴的Msat、Aex、Ku1)配置与优化均有涵盖。文章深入解析了特征长度计算、初始化方法、弛豫与动力学模拟流程,并分享了并行计算与参数扫描等效率提升技巧,旨在帮助用户快速上手并优化模拟工作流。

moss5的博客 702

java foreach用法_Java十大简单性能优化

以下是Java中最容易进行的10个性能优化:1.使用StringBuilder这几乎是所有Java代码中的默认设置。尽量避免+操作员。当然,您可能会争辩说它StringBuilder无论如何都是语法糖,例如:1个String x = "a" + args.length + "b";…编译成 0个新的java.lang.StringBuilder [16] 3 dup 4 ldc <Strin...

weixin_39956558的博客 523

通达信短周期指标盘中实时监控与预警选股实战

本文详细介绍了通达信短周期指标在盘中实时监控与预警选股中的实战应用。通过分时指标改造、多股同列监控技巧及预警策略优化,帮助短线交易者捕捉转瞬即逝的交易机会,提升选股效率与准确性。重点解析了如何避免假信号干扰及系统卡顿问题,并探讨了从预警到自动交易的进阶应用。

weixin_29230805的博客 887

关于equals在Java集合中的思考

1.“==”与“equals”的区别 "=="用于判断对象是否为同一个对象(基本数据类型比较值相等,引用数据类型比较对象地址是否相等) equals()的比较存在两种情况: 类没有重写equals()方法时,等价于"=="; 类重写equals()方法时,要依据重写方法内容而定,大部分情况会按照值判定,即对象储存的值相同就会返回”true"。 例子如下: public class test1 { public static void main(String[] args) { Str

qq_38593079的博客 781

强化学习_06_pytorch-TD3实践(BipedalWalkerHardcore-v3)

DDPG的critic会高估, 从而导致actor策略失败。TD3是增加了三个关键技巧优化DDPG。经过优化后的TD3(Twin Dalayed DDPG 双延迟深度确定性策略梯度算法)适合于具有高维连续动作空间的任务。

RL小站 2688

OpenClaw实战五|企业文档AI助理:对接内部知识库+自动答疑+文档生成,员工自助查资料零等待

企业最大的隐性成本,不是设备、不是房租,而是内部知识的混乱与流失。OpenClaw企业文档AI助理,本质是给企业做了一个7×24小时在线、永不疲倦、精准无误、自动更新的内部知识管家。它不替代HR、行政、IT,而是把他们从无穷无尽的重复问答、机械文档编写里解放出来,去做更有价值的管理、服务、优化工作。对中小企业来说,不用买昂贵的知识库系统、不用招开发、不用做复杂集成,一台私有化服务器,两天就能落地,性价比拉满。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 143

面试点:Java 中 hashCode() 和 equals() 的关系

在学习 hashCode() 和 equals() 之间的关系之前, 我们有必要先单独地了解他俩的特点.

TimeFriends 857

135、高通 ChromaTix 调优工具入门:参数含义、调优流程与效果对比

本文介绍了高通ChromaTix色彩调优工具的核心使用要点:1. ChromaTix是位于ISP管线中的色彩处理系统,核心任务是将原始色彩映射为符合人眼感知的"舒适"效果;2. 重点解析了饱和度、色调、亮度相关饱和度等关键参数的实际含义和调试陷阱;3. 分享了四步调优流程,强调需要基于多场景数据验证;4. 通过案例展示了参数调整带来的色彩改善效果;5. 总结了实用建议,包括保持单一变量调试、量化评估色差、关注极端场景表现等。文章指出ChromaTix调优是平衡不同场景需求的"妥协艺术",需要结合客观数据和主

sundong_81的博客 106

java 中 的 == 和 equals以及堆栈的思考

1.关于 java 中 的 == 和 equals 的比较结果,衍生基本类型和引用类型的比较特点: 众所周知,java世界内 分为两种数据类型: 1).第一种就是基础数据类型 byte short int long 整数数据类型 float double 小数数据类型 boolean 布尔类型 char 单字符类型 2).第二种为引用数据类型: 例如 String 字符串; 数组 ; 类 ok,基...

voyager911的博客 216

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Java基础之重写equals方法的同时为什么要重写hashCode方法

public boolean equals(Object obj) 指示其他某个对象是否与此对象“相等”。  equals 方法在非空对象引用上实现相等关系:  自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。  对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回true。 

ljh_learn_from_base的博客 468

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

java中的不等号_java中 等号= 和 equals 的区别

一句话概括:==比较的是两个对象的引用(即内存地址)是否相等,而equals()比较的是两个对象的值(即内存地址里存放的值)是否相等。当 然equals()在个别类中被重写了那就例外了。详细论述:eqauls 与 = =之异同1)比较方式角度:= =是面向过程的操作符;equals是面向对象的操作符= =不属于任何类,equals则是任何类(在Java中)的一个方法;我们可以1)Primitive...

weixin_42188533的博客 1386

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

关于重写hashCode和equals方法的一些思考

  经常能看到重写equals方法就需要重写hashCode方法的说法,这点也很好理解,假如重写equals使得两个对象通过equals判断为真 ,但是如果hashCode计算出来的值如果不一样,就会发生矛盾,就是明明两个对象是一样的,但是却会被映射到不同位置,这样子的话,hashMap或者hashSet之类的哈希结构就会存储多个相同的对象。还可以通过一个例子理解 Map<String,Value> map1 = new HashMap<String,Value>();

今天打卡Leetcode了吗 1828

java中关于==和equals()的思考

首先:在java中内存分为“栈”和“堆”这两种(Stack and Heap).基本数据类型存储在“栈”中,对象引用类型实际存储在“堆”中,在栈中只是保留了引用内存的地址值,就好像知道你家门牌号码就可以找到你家。在Java中利用"=="比较变量时候,系统使用变量在stack(栈)中所存的值来作为对比的依据,基本数据类型(int float double boolean)在stack中所存的值就是其

1106

由equals()引发的getClass()思考

场景描述 阅读文章中一句话;如果在子类中重新定义equals,就要在其中包含调用 super.equals(other)。 自己测试 创建父类BaseEntity public class BaseEntity { private String name; String getMyName(){ return name; } @Overri...

VinDePro的博客 502

Java中的 == 和 equals 区别

Java中的 == 和 equals 到底有什么区别? 提到Java的 == 和 equals,很多人就会说 == 比较的值(地址), equals比较内容,这句话到底对不对? equals是object类的一个方法,定义如下: public boolean equals(Object obj) { return (this == obj); } 我们看到,当调用equals时, 实际还是调用...

weixin_44588771的博客 296

java中equals, hashcode的思考

今天看到一篇文章不错,共享一下:  1.如果是基本变量,没有hashcode和equals方法,基本变量的比较方式就只有==; 2.如果是变量,由于在java中所有变量定义都是一个指向实际存储的一个句柄(你可以理解为c++中的指针),在这里==是比较句柄的地址(你可以理解为指针的存储地址),而不是句柄指向的实际内存中的内容,如果要比较实际内存中的内容,那就要用equals方法,但是!!! 如果

bigbin的专栏 1513

由==和equals引发的思考和探索

在java面试题中,==和equals的区别时很常见的一道题,一般答案来说是这样的: ==:如果是基本数据类型,会比较的是变量的值,如果是引用数据类型比较的是地址值(两个对象是否指向同一块内存); equals:没有重写比较的是两个对象的地址值,重写之后比较的是变量的值。 于是我去查看了String类中的源码: public boolean equals(Object anObject)...

qq_38950073的博客 270

java重写equals方法时,为什么还需要重写hashCode

在说这个问题之前,先说下equals和hashCode各自的作用 equals: 判断两个对象是否相等所调用的方法。 public boolean equals(Object obj) { return (this == obj); } 瞜一眼java的Object类的equals方法代码,很明显这个方法是比较两个对象的地址是否相等 hascode: 我也不知道这个方法有啥作用,咱们姑且算它是返回当前对象的唯一code码吧。可以理解为数据库表的主键 public

码眼的博客 907

java equals方法实现_Java 中Object类与equals方法

Object类中的equals()总说Object类首先介绍一下Object类。Class {@code Object} is the root of the class hierarchy.Every class has {@code Object} as a superclass. All objects,including arrays, implement the methods of t...

weixin_39863017的博客 288

从equals思考对“正念”的认知

正念

weixin_45149147的博客 291

Java equals方法与hashCode

文章目录1. Object equals方法与hashCode2. 重写equals方法重写的equals方法需要满足五个性质重写equals方法必须重写equals方法结语参考文献 1. Object equals方法与hashCode Java Object类中equals方法为: public boolean equals(Object obj) { return (this == obj); } 所以如果没有重写Object类的equals方法,那么equals与==计算结

flyieen的博客 1430
上一篇: Linux: date 和 随机数
下一篇: JAVA: 堆,栈,常量池
Coder-Qian
博客等级 码龄11年 63粉丝 73原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值