对象相等比较

2023-11-04

String的相等比较

对于String类型而言,一般用“==”或者equales做相等比较,前者比较字符串的引用,后者比较字符串的值。

字符串常量的值存储于常量池中,只要值相同,那么引用的就是同一个字符串常量,也就是说,==和equals效果一样。

字符串对象存储于堆中,不同的对象在堆上的内存地址是不一样的。因此,创建两个值相等的String对象,其引用的地址是不相等的。也就是说,用 == 比较时不等,用equals比较时相等。

Integer的相等比较

Integer是int的包装类型,通常直接赋值即可。比较时用==还是equals呢?看下面的例子:

Integer t1 = 129;
Integer t2 = 129;
Integer t3 = 119;
Integer t4 = 119;
System.out.println(t1 == t2);
System.out.println(t3 == t4);

输出结果是false,true。

原因是:对于在-128~127之间的数,Integer使用的是内部缓存值,在此范围之外的数,Integer会在堆上创建对象。t1和t2是堆上的不同对象,所以引用不相等。而t3和t4是内部缓存的值,引用相等。

显式new出来的Integer对象,必然会在堆上创建对象,其引用是不同的。
Integer和int进行==比较时,会自动拆箱进行值的比较。

HashMap中key的相等比较

对于HashMap的key,如果是基本数据类型,则直接进行值的比较。而如果是引用类型呢?

HashMap底层是用数组和链表存储的,当链表长度超过8时会转化为红黑树。根据key进行查找时,先根据hashCode找到数组上的位置,如果该位置上有多个元素,则继续通过equals方法判断值是否相等。

当两个复杂对象作为map的key相等时,必然先要保证hashCode相同,其次equals也要为true。也就是说,使用复杂对象作为map的key时,需要重写hashCode和queals方法。

如果只重写hashCode方法不重写equals方法,则默认的equals方法会进行内存地址的比较,必然是不同的。如果不重写hashCode方法而仅仅重写equals方法,则首先数组上的位置就不同(当然,发生哈希碰撞时例外),对象自然不会相同。

看下面的例子:

public static class Student {

    private String name;

    private String id;

    public Student(String name) {
        this.name = name;
    }

    public Student(String name, String id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

}

public static void main(String[] args) throws Exception {
    Student stu1 = new Student("aa", "1");
    Student stu2 = new Student("aa", "1");
    Map<Student, String> map = new HashMap<>();
    map.put(stu1,"1");
    map.put(stu2,"2");
    System.out.println(map.size());
}

输出为2。

在这个例子中,map中放入Student类型对象作为key,如果不重写比较方法的话,放入的对象是不同的(默认的比较方法继承于Object类,比较的是内存地址)。

重写hashCode和queals

对Student类的比较方法进行重写:

public static class Student {

    private String name;

    private String id;

    public Student(String name) {
        this.name = name;
    }

    public Student(String name, String id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof Student)) {
            return false;
        }
        Student s = (Student) o;
        return Objects.equals(id, s.getId()) && Objects.equals(name, s.getName());
    }

}

public static void main(String[] args) throws Exception {
    Student stu1 = new Student("aa", "1");
    Student stu2 = new Student("aa", "1");
    Map<Student, String> map = new HashMap<>();
    map.put(stu1,"1");
    map.put(stu2,"2");
    System.out.println(map.size());
}

输出为1,说明stu2和stu1相同,添加元素的key相同时,后者覆盖了前者。

还可以用Apache Commons Lang中的API来实现重写:

@Override
public int hashCode() {
    return new HashCodeBuilder(17, 37).append(name).append(id).toHashCode();
}

@Override
public boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof Student)) {
        return false;
    }
    Student s = (Student) o;
    return new EqualsBuilder().append(name, s.getName()).append(id, s.getId()).isEquals();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对象相等比较 的相关文章

  • java类的生命周期

    如图 1 加载 我们编写一个java的源文件 经过编译后生成一个后缀名为 class的文件 这结合四字节码文件 java虚拟机就识别这种文件 java的生命周期就是class文件从加载到消亡的过程 关于加载 其实 就是将源文件的class文
  • Calendar的使用

    Calendar Calendar是一个抽象类 构造器被protected修饰 需要通过getInstance 获取实例 public static void main String args Calendar instance Calen
  • mac上使用IntelliJ IDEA运行项目

    一 Mac OSX系统下安装Tomcat 1 下载Tomcat官方下载地址 2 解压Tomcat到目录 Library 中 并把文件夹名由 apache tomcat 6 0 16 改为 Tomcat 3 打开 应用程序 Applicati
  • 字符“&”在XML文件中需要被转义

    今天弄Mybatis的配置文件时 因为这样一条语句
  • 什么是多态?对于多态的理解....

    什么是多态 我们都知道面向对象有四个基本特性 抽象 封装 继承 多态 概括可以理解为 抽象 封装 继承 是多态的基础 多态是抽象 封装 继承的表现 多态 是Java中非常重要的一部分 简单理解 不同类的 对象 对同一消息 做出了不同的响应就
  • 5、面向对象的设计思想

    一 面向对象设计思想 1 1 面向过程的设计思想与面向对象的设计思想 例如 我要去新疆 面向过程 我开车 我挂挡 我踩油门 我过河北 我过陕西 面向对象 我命令车去新疆 车怎么去不关我事 信息封装在这这个类的内部 我不用去了解车整个开动的过
  • Java中变量的作用域【Java基础】

    最近在看 Thinking in Java 想把Java基础再巩固一下 在博客上遇到的以前没注意到的知识点或者较难的知识点记录下来 与大家分享 Java中的基本类型变量的作用域为 int x 1 变量x的作用域只在大括号内 System o
  • java Map集合

    目录 一 介绍 二 HashMap 三 TreeMap 四 LinkedHashMap 一 介绍 Java中的Map是一种键值对的集合数据类型 用于存储无序的 不重复的键值对 它提供了快速的查找和访问功能 可以根据键来获取值 常见的Map实
  • [透彻]为什么要前后端分离?

    前后端分离的意义 前后端分离 已成为互联网项目开发的业界标准使用方式 前后端分离 会为以后的大型分布式架构 弹性计算架构 微服务架构打下坚实的基础 核心思想 前端页面调用后端的restuful api接口 并使用json数据进行交互 服务器
  • 第一个java程序helloworld代码的编写

    第一个java程序helloworld代码的编写 文章目录 第一个java程序helloworld代码的编写 toc 一 项目 二 认识JVM JRE和JDK 2 1 JVM是什么 2 2 JVM的主要功能和作用 2 3 JRE和JDK J
  • springboot跳转页面

    SpringBoot里面只有src目录 在src main resources下面有两个文件夹 static 和 templates springboot默认static中放静态页面 而templates中放动态页面 themleaf和fr
  • Java中count++的坑

    最近做了一道题 非常容易落入陷阱 当count初始值为0 count count 和count count 运行出来的结果是不一样的 count count 运行出来的结果依旧为0 这是因为JVM运行时 会把count变量拷贝到到临时变量区
  • jeecgboot问题解决方案

    常见问题Q A JEECG老版在线文档 点击进入 1 后台访问提示token错误 报错截图 解决方案 JeecgBoot后台的所有请求访问 增加了token机制 所以不能直接访问后台 而需要通过前台登录才能访问 默认前台访问地址 http
  • 求一个数组的最大值最小值及其下标

    求一个数组的最大值最小值及其下标 思路 假定一个数为最大值 如果有个数比假定的最大值还大 那么该数就为最大值 最小值同理 使用for循环 public class MaxMin public static void main String
  • JAVA--GUI(2)--布局

    布局 为了更好适应不同平台而引入的概念 Java的布局管理器是一个实现了LayoutManager接口的实例 用户无法设置setLocation 这些方法 如果想自己设置则需要取消布局管理器 采用布局管理器 边界布局 顺序布局 网格布局 卡
  • SM2加解密、签名验签

    导论 SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法 在我们国家商用密码体系中被用来替换RSA算法 国产SM2算法 是基于ECC的 但二者在签名验签 加密解密过程中或许有些许区别 目前鄙人还不太清楚 后期有机会的话
  • java动态代理简单实例

    java动态代理简单实例 package hello import java lang reflect InvocationHandler import java lang reflect Method import java lang r
  • 设计模式(2)

    2 2 结构型模式 结构型模式一共有七种 其中 适配器模式和装饰模式统称为包装模式 装饰模式和代理模式的类图基本相同 但目的不同 这些有相似目的或者有相似结构的模式需要对其概念辨析清楚 才能较好地掌握 下面将对结构型模式分别进行介绍 2 2
  • 关于svn如何上传一个完整的项目

    注意 请一定要按照该步骤进行操作 请上传新项目时将项目名称进行规范命名 例如原始文件是arrange v2 将此项目需要注入新的医院 则命名为 arrange 某医院名称 门诊或者医技或者药房 v2 重新命名文件夹名称快捷键 F12 一 先
  • 黑豹程序员-字符串中查找出重复的字符串

    Collections frequency codeList element 字符串element 在codeList集合中重复的次数 List

随机推荐

  • vue 绘制体温单与三测单组件 实现前端js打印

    更新 代码开源 https github com mydaoyuan my development 有帮助请帮忙点个 start 企鹅 1534815114 新上 麻醉单 和 患者时间轴 在下面地址就可以看到 新的一个版本完全重写了体温单
  • Windows无法与设备或资源(主DNS服务器)通信的解决方法

    前言 这几天 Windows更新后 连接的手机热点似乎出现了一些小问题 网络总是不稳定 而且浏览器等也出现上不了网的问题 解决方法 当电脑出现连接上WLAN后却无法上网的问题时 1 首先可以右键点击桌面右下角处的网络图标 在弹出的菜单中选择
  • java的inputstream_java中inputstream的使用

    java中的inputstream是一个面向字节的流抽象类 其依据详细应用派生出各种详细的类 比方FileInputStream就是继承于InputStream 专门用来读取文件流的对象 其详细继承结构如图 我们发现 是从抽象类InputS
  • 虚拟vpc服务器搭建,在AWS上搭建VPC三层架构的私有网络

    概述 这里使用的是aws的vpc 因为使用aws的该功能 需要账户绑定授权usd的信用卡 没有的话 就操作不了 用aws的好处是 很多功能是有限时间内是免费的 可以很好的拿来做练习 什么是vpc VPC Virtual Private Cl
  • 浅析Android如何从不同的层次保证安全性

    Android上的安全机制可以基本都是从两个方面来进行 1 应用沙盒2 权限约束 先了解一下基本知识 Android是一个分层操作系统 由个4层组成 分别是 Linux Kernel Native Userspace Android Fra
  • 用googletest写cpp单测

    框架概述 Google Test 也称为 googletest 是由 Google 开发的 C 单元测试框架 它的首个版本是在2004年发布的 作为 Google 内部的测试框架使用 随后 Google Test 在开源社区中得到广泛应用
  • 利用Burp suit扫描漏洞

    利用Burp suit扫描漏洞 一 开始准备 1 1burp是利用本地代理抓取所传送的数据包的 所以我们要设置浏览器的代理 打开Firefox浏览器 在地址栏输入http 192 168 1 3 回车进行访问 单击 选项 如图1所示 图1
  • Enterprise Architect UML建模

    Enterprise Architect UML建模 前言 UML建模资料已经很多了 有人想用有人不用 有人会用也有人不会用 本文只是作者的一篇UML建模总结 不想去写太细 因为真正的你去用下 去画下就基本都会了 工具毕竟是工具 设计和思想
  • MySQL数据库连接超时自动断开的解决方案

    一次朋友小聚 大家谈起了技术问题 一个在国企里的同学说 他们的系统很奇怪 每天早上都得重启一下应用程序 否则就提示连接数据库失败 他们都不知道该怎么办 我当时稍加思索说了一下 应该是连接超时引起的 这样的问题在我的业务场景没有遇到过 所以我
  • 三菱服务器显示代码d2,三菱QD64D2手册QD64D2用户手册 - 广州凌控

    SRAM E2PROM存储卡 RAM容量 64KB E2PROM容量 64KB 输入输出点数 4096点 输入输出元件数 8192点 程序容量 1000 k步QD64D2用户手册 处理速度 0 0095 s 程序存储器容量 4000 KB
  • Java--SpringMVC之处理器方法返回值

    一 处理器方法返回值 使用 Controller注解的处理器方法 返回值会有四种类型 ModelAndView String Void 自定义Java对象 1 ModelAndView ModelAndView 有数据和视图 若处理器方法处
  • python如何安装第三方库 request_python 安装第三方库 request时报错

    今天安装request时报错 F pythonFile gt pip install requests Collecting requests Downloading requests 2 24 0 py2 py3 none any whl
  • 饼图 echarts -无数据时给提示

    div class thirdEchartBody div mport pieGenderChartConfig from js passengerFlowAnalysisConfig js mounted this getGenderCh
  • 永别了gitee图床,阿里云图床我来啦!!!

    文章目录 缘由 前期准备工作一 下载了 Typora 和Picgo 1 本人 Typora 版本 2 本人Picgo 版本 准备工作二 注册阿里云账号 重要 一定要看一下 步骤一 点击控制台 步骤二 选择 对象储存 并开通 步骤三 点击左侧
  • javascript 大文件下载,分片下载,断点续传

    javascript 大文件下载 分片下载 断点续传 文章目录 javascript 大文件下载 分片下载 断点续传 1 获取文件大小 2 切片下载 3 合并数据 4 下载到本地 5 成功 6 完整代码 既然是断点续传 自然离不开分片下载
  • 小程序自动更换标题文字及icon的方法

    一 动态生成底部tabBar的icon和文字 wx setTabBarItem index 2 text 商品 iconPath assets StoreLife 2x png selectedIconPath assets storeLi
  • 关于Mysql的驱动(org.gjt.mm.mysql.Driver)问题

    目前我知道的连接mysql的驱动有两个 一个是org gjt mm mysql Driver 另外一个是com mysql jdbc Driver 我做毕设时使用的org gjt mm mysql Driver 这个比较老了 现在使用的比较
  • QT VS与QT的项目配置

    VS中添加Qt模块 VS中添加Qt文件
  • 单端、差分、伪差分输入

    单端信号 单端信号 single end 是相对于差分信号而言的 单端输入指信号有一个参考端和一个信号端构成 参考端一般为地端 ADC单端输入 比如说UART232串口中 发送端TXD 接收端RXD 参考端是地 GND 是典型的单端信号输入
  • 对象相等比较

    String的相等比较 对于String类型而言 一般用 或者equales做相等比较 前者比较字符串的引用 后者比较字符串的值 字符串常量的值存储于常量池中 只要值相同 那么引用的就是同一个字符串常量 也就是说 和equals效果一样 字