【Java SE】对象的比较

🥰🥰🥰来都来了,不妨点个关注叭!
👉博客主页:欢迎各位大佬!👈

在这里插入图片描述
本期内容满满干货,将会深入介绍对象与对象之间是如何进行比较的,我们知道基本数据类型是可以直接比较大小的,Java中引用类型的变量不能直接按照大于或者小于的方式进行比较,那为什么==可以比较呢?我们一起带着这些问题来了解本期内容

文章目录

  • 1. 等于关系
    • 1.1 ==
    • 1.2 equals方法
    • 1.3 ==和equals方法的区别
  • 2. 大于/小于关系
    • 2.1 实现Comparable接口
    • 2.2 Comparator比较器
    • 2.3 三种重写方法的比较

1. 等于关系

==可以比较引用数据类型的原因
对于用户实现自定义类型,都默认继承Object类,Object类中提供equals方法,==默认情况下调用的就是equals方法,该方法的比较规则是:不是比较引用变量引用对象的内容,而是直接比较引用变量的地址,但有些情况下该种比较就不符合题意,这时就需要重写equals方法,达到我们的目的
Object中equals的实现,可以清楚的看到,直接比较的是两个引用变量的地址

 public boolean equals(Object obj) {
        return (this == obj);
    }

1.1 ==

class Person {
    public String name;
    public String gender;
    public int age;

    Person(String name,String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String toString() {
        return "[" + this.name + ":" + this.gender + " "+ this.age + "]";
    }
}


public class Test {
    public static void main(String[] args) {
        //1,==比较基本数据类型
        int a = 10;
        int b = 10;
        System.out.println(a == b);

        //2. ==比较引用数据类型
        Person[] person = new Person[] {
                new Person("泡泡","女",19),
                new Person("泡泡","女",19),
                new Person("柚柚","女",25),
                new Person("球球","男",25)
        };
        System.out.println(person[0] == person[1]);
        System.out.println(person[0].equals(person[1]));
    }

}

打印结果为:
在这里插入图片描述\

1.2 equals方法

有些情况下,需要比较的是对象中的内容,这时需要重写equals方法,比如上述例子,我们可以看到person[0]与person[1]这两个对象的内容都是一样的,所以我们希望equals方法比较的时候返回的是true

class Person {
    public String name;
    public String gender;
    public int age;

    Person(String name,String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String toString() {
        return "[" + this.name + ":" + this.gender + " "+ this.age + "]";
    }

    @Override
    public boolean equals(Object o) {
        //自己和自己比较
        if(this == o) {
            return true;
        }
        //o是null对象或者o不是Person类
        if(o == null || !(o instanceof Person)) {
            return false;
        }

        Person p = (Person)o;
        //基本数据类型如age为int类型可以直接用==比较
        //引用类型最好还是用equals比较
        return name.equals(p.name) && gender.equals(p.gender) && age == p.age;
    }
}


public class Test {
    public static void main(String[] args) {
        //比较引用数据类型
        Person[] person = new Person[] {
                new Person("泡泡","女",19),
                new Person("泡泡","女",19),
                new Person("柚柚","女",25),
                new Person("球球","男",25)
        };
        System.out.println(person[0] == person[1]);
        System.out.println(person[0].equals(person[1]));
    }

}

打印结果如下:
在这里插入图片描述
因为==实际上还是调用的默认equals方法,对象的地址进行比较,所以打印false,而重写了equals后,再进行比较,我们看到person[0]与person[1]的内容完全一致,所以返回true

equals方法覆写的通用步骤:

  1. 如果指向同一个对象,返回 true
  2. 如果传入的为 null或者传入的对象类型不是该类的,返回false
  3. 按照自己的规则,完成类的实现目标比较
  4. 注意在重写的时候用其他引用类型的比较也需要 equals,例如这里的name,gender的比较

缺点】equals方法只能比较是否相等,不能按照大于、小于的方式进行比较

1.3 ==和equals方法的区别

==
对于基本数据类型,比较的是值
对于引用数据类型,比较的是对象的内存地址

因为Java只有值传递,所以,==不管是比较基本数据类型还是引用数据类型变量, 其本质比较的都是值,只是引用类型变量存的值是对象的地址

equals方法
equals方法比较的也是对象的内存地址,但是可以重写equals,按照自己的比较规则来比较内容是否相等

2. 大于/小于关系

下面我们来看看这个例子,给一个对象数组排序,能否直接用已经有的sort方法呢~

class Person {
    public String name;
    public String gender;
    public int age;

    Person(String name,String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String toString() {
    return "[" + this.name + ":" + this.gender + " "+ this.age + "]";
    }

}
public class Test1 {
    public static void main(String[] args) {
        Person[] person = new Person[] {
                new Person("泡泡","女",19),
                new Person("西西","男",33),
                new Person("柚柚","女",25),
                new Person("球球","男",25)
        };

        Arrays.sort(person);
        System.out.println(Arrays.toString(person));

    }
}

运行结果:运行出错,抛出异常
在这里插入图片描述
答案是显然不行的,因为整数之间是可以直接比较,大小关系明确。但是两个学生对象的大小关系无法确定,需要我们自己额外指定,下面介绍两种方法:

2.1 实现Comparable接口

即Person类实现Comparable接口,并重写该接口的compareTo方法
Comparble是JDK提供的泛型的比较接口类,T代表泛型,实现过程具体如下:

public interface Comparable<T> {
    // 返回值:
    // < 0: 表示this指向的对象小于o指向的对象
    // == 0: 表示this指向的对象等于o指向的对象
    // > 0: 表示this指向的对象大于o指向的对象
    int compareTo(T o);
}

在这里插入图片描述
(一) 以下为使用Comparable接口,按上述例子,年龄进行从大到小排序的代码:

class Person implements Comparable{
    public String name;
    public String gender;
    public int age;

    Person(String name,String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String toString() {
    return "[" + this.name + ":" + this.gender + " "+ this.age + "]";
    }

    public int compareTo(Object o) {
        Person p = (Person)o;
        if(this.age > p.age) {
            return -1;
        }else if(this.age < p.age) {
            return 1;
        }else {
            return 0;
        }
        //上述判断可以直接写成
        //return p.age - this.age; 
        //该两个对象比较打印结果为年龄差值
    }

}
public class Test1 {
    public static void main(String[] args) {
        Person[] person = new Person[] {
                new Person("泡泡","女",19),
                new Person("西西","男",33),
                new Person("柚柚","女",25),
                new Person("球球","男",25)
        };
        //两个对象的比较
        System.out.println(person[0].compareTo(person[1]));
        //对象数组排序
        Arrays.sort(person);
        System.out.println(Arrays.toString(person));

    }
}

运行结果如下:
在这里插入图片描述
解释说明
(1) 表达当前对象大于参数对象
在这里插入图片描述
(2) 在sort方法中会自动调用compareTo方法,compareTo的参数是Object,其实传入的是Person类型的对象,比较当前对象与参数对象的大小关系,可以自己定义比较哪个参数(比如这里按年龄来算的)

1> 如果当前对象应排在参数对象前,返回小于0的数字
2> 如果当前对象应排在参数对象后,返回大于0的数字
3> 如果当前对象与参数对象不分先后,返回0

(3) 如果想让年龄从小到大排序呢~即把大于号改成小于号,小于号改成大于号,记住想让当前对象排在参数对象前,返回值需要小于0

 public int compareTo(Object o) {
        Person p = (Person)o;
        if(this.age < p.age) {
            return -1;
        }else if(this.age > p.age) {
            return 1;
        }else {
            return 0;
        }
    }
 public int compareTo(Object o) {
        Person p = (Person)o;
      	return this.age - p.age;
    }

(二) 以下为使用Comparable接口带泛型的代码:

class Person implements Comparable<Person>{
    public String name;
    public String gender;
    public int age;

    Person(String name,String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String toString() {
    return "[" + this.name + ":" + this.gender + " "+ this.age + "]";
    }

    public int compareTo(Person o) {
        return this.age - o.age;
    }

}
public class Test1 {
    public static void main(String[] args) {
        Person[] person = new Person[] {
                new Person("泡泡","女",19),
                new Person("西西","男",33),
                new Person("柚柚","女",25),
                new Person("球球","男",25)
        };
        System.out.println(person[0].compareTo(person[1]));
        Arrays.sort(person);
        System.out.println(Arrays.toString(person));

    }
}

打印结果如下:年龄按从小到大排序
在这里插入图片描述
缺点】容易写死,写死就固定下来了~
总结即可以在一个类中实现Comparable接口,并实现该接口的方法comparaTo方法,可按照自己指定规则,进行比较排序

2.2 Comparator比较器

按照比较器比较的方式具体步骤如下:
(1) 用户自定义比较器类,实现Comparator接口

 public interface Comparator<T> {
        // 返回值:
        // < 0: 表示o1指向的对象小于o2指向的对象
        // == 0: 表示o1指向的对象等于o2指向的对象
        // > 0: 表示o1指向的对象大于o2指向的对象
        int compare(T o1,T o2);
    }

在这里插入图片描述
(2) 重写Comparator中的compare方法,上述例子代码如下:

import java.util.Comparator;

class Person implements Comparable<Person>{
    public String name;
    public String gender;
    public int age;

    Person(String name,String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String toString() {
        return "[" + this.name + ":" + this.gender + " "+ this.age + "]";
    }


    @Override
    public int compareTo(Person o) {
        return this.age-o.age;
    }
}

class PersonAgeComparator implements Comparator<Person> {

    @Override
    public int compare(Person o1, Person o2) {
        return o2.compareTo(o1);
    }
}

public class Test2 {

    public static void main(String[] args) {
            Person[] person = new Person[] {
                new Person("泡泡","女",19),
                new Person("西西","男",33),
                new Person("柚柚","女",25),
                new Person("球球","男",25)
        };

        //定义比较器对象
        PersonAgeComparator tor = new PersonAgeComparator();
        //使用比较器对象进行比较
        System.out.println(tor.compare(person[0],person[1]));
    }
}

运行结果:
在这里插入图片描述注意
(1) Comparator是java.util 包中的泛型接口类,使用时必须导入对应的包,即import java.util.Comparator;
(2) 这里不能直接使用Arrays.sort来排序对象数组,因为没有重写compareTo方法,sort方法中会自动调用compareTo方法

2.3 三种重写方法的比较

在这里插入图片描述💛💛💛本期内容回顾💛💛💛
在这里插入图片描述✨✨✨本期内容到此结束啦~下期再见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/608964.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用 docker-compose 搭建个人博客 Halo

说明 我这里使用的是 Halo 作为博客的工具&#xff0c;毕竟是开源了&#xff0c;也是使用 Java 写的嘛&#xff0c;另外一点就是使用 docker 来安装&#xff08;自动挡&#xff0c;不用自己考虑太多的环境因素&#xff09;&#xff0c;这样子搭建起来更快一点&#xff0c;我们…

【STM32 |新建一个工程】基于标准库(库函数)新建工程

目录 STM32开发方式 库函数文件夹 建工程步骤 库函数工程建立 建立工程总结 STM32开发方式 目前stm32的开发方式主要有基于寄存器的方式、基于标准库的方式&#xff08;库函数的方式&#xff09;、基于HAL库的方式基于库函数的方式是使用ST官方提供的封装好的函数&…

17、线上系统中垃圾回收参数的精准调校指南

17.1、前文回顾 在上一篇文章中,我们已经通过逐步的图解方式,详细解释了CMS垃圾回收的运行机制。简单来说,CMS垃圾回收器采用了四个阶段来进行垃圾回收,以尽量避免长时间的“Stop the World”现象。这四个阶段分别是:初始标记、并发标记、重新标记和并发清理。 在初始标…

AlphaFold 3 可以预测所有生命分子的结构和相互作用

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

《二十二》Qt 音频编程实战---做一个音频播放器

1.UI界面制作 作为一个音乐播放器&#xff0c;最基础的肯定就是播放、暂停、上一首以及下一首&#xff0c;为了使这个界面好看一点&#xff0c;还加入了音量控制、进度条、歌曲列表等内容&#xff0c;至于这种配色和效果好不好看&#xff0c;我也不知道&#xff0c;个人审美一如…

【Java基础】数学相关的方法

基本方法 Return TypeFunctionDescriptionstatic doublerandom()返回值为 double&#xff0c;值为正号&#xff0c; ≥0.0 <1.0static 数值类型abs(数值类型 a)返回值为a的绝对值static doublepow(double a, double b)将第一个参数的值返回到第二个参数的幂static doublesq…

Taro 快速开始

大家好我是苏麟 , 今天聊聊Trao. 官网 : Taro 介绍 | Taro 文档 (jd.com) 点击快速开始 全局安装 CLI 初始化一个项目 选择配置 : 根据自己需求选择 安装失败先不用管 , 用前端工具打开项目 npm install 安装 , 显示安装失败 怎么解决 ? : 查看报错信息 百度 , 问 AI 工具 运…

第十讲:指针(2)

第十讲&#xff1a;指针&#xff08;2&#xff09; 1.对于数组名的理解1.1验证数组名就是数组首元素的地址1.2sizeof数组名和&数组名1.2.1sizeof数组名1.2.2&数组名 2.使用指针访问数组3.数组传参的本质4.冒泡排序5.二级指针6.指针数组7.指针数组模拟二维数组 这一讲讲…

TODESK怎么查看有人在远程访问

odesk怎么查看有人在远程访问 Todesk作为一款远程桌面控制软件&#xff0c;为用户提供了便捷的远程访问与控制功能。但在享受这种便利的同时&#xff0c;许多用户也关心如何确保自己设备的安全&#xff0c;特别是如何知道是否有人在未经授权的情况下远程访问自己的电脑。本文将…

TODESK远程开机的原理

在现代计算机技术飞速发展的背景下&#xff0c;远程控制软件成为我们日常工作中不可或缺的工具。其中&#xff0c;ToDesk作为一款高效且易用的远程控制软件&#xff0c;备受用户青睐。那么&#xff0c;ToDesk远程开机的原理是什么呢&#xff1f;本文将为你揭晓这个秘密。 KKVie…

《TAM》论文笔记(上)

原文链接 [2005.06803] TAM: Temporal Adaptive Module for Video Recognition (arxiv.org) 原文代码 GitHub - liu-zhy/temporal-adaptive-module: TAM: Temporal Adaptive Module for Video Recognition 原文笔记 What&#xff1a; TAM: Temporal Adaptive Module for …

Disk Doctor for Mac 免激活版:数据安全守卫者

数据丢失是每个人都可能遇到的问题&#xff0c;但Disk Doctor for Mac能让这个问题迎刃而解。这款强大的数据恢复软件&#xff0c;能迅速找回因各种原因丢失的数据。 Disk Doctor采用先进的扫描技术&#xff0c;能深入剖析磁盘&#xff0c;找到并恢复被删除或损坏的文件。同时&…

NREL概述了串联电池的前进方向

研究人员表示&#xff0c;串联技术将帮助我们在2050年达到75太瓦的光伏发电量&#xff0c;但行业合作将是关键 美国能源部国家可再生能源实验室&#xff08;NREL&#xff09;的研究人员已经制定了一份路线图&#xff0c;说明如何将串联太阳能电池&#xff08;特别是那些结合了不…

吉林事业编报名照要求<50kb怎么压缩

吉林事业编报名照要求&#xff1c;50kb怎么压缩

如何安装ElasticSearch及相关件

一、简介 ElasticSearch是什么&#xff1f; elasticsearch简写es&#xff0c;es是一个高扩展、开源的全文检索和分析引擎&#xff0c;它可以准实时地快速存储、搜索、分析海量的数据。 ElasticSearch 插件 elasticsearch-head是一款专门针对于elasticsearch的客户端工具&am…

基于FPGA的视频矩阵切换方案

一、单个显示设备的系统方案&#xff1a;会议室只有1个显示设备 会议室的信号源有很多&#xff0c;但是显示设备只有1个&#xff0c;这个时候最佳方案是使用切换器。 &#xff08;1&#xff09;切换器&#xff08;控制方式&#xff1a;遥控器、软件、机箱面板、中控&#xff…

Relaxed MemoryConsistency

SC和TSO都被称之为强&#xff08;strong&#xff09;保序模型&#xff1b; because the global memory order of each model usually respects (preserves) per-thread program order&#xff1b;回想一下&#xff0c;对于load和store的所有四种组合&#xff08;Load -> Lo…

FPGA+HDMI转换方案,用于网络直播切换直播画面,客户应用:直播,自媒体

FPGAHDMI转换方案&#xff0c;用于网络直播切换直播画面 客户应用:直播&#xff0c;自媒体 主要功能: 1.支持多路HDMI高清输入/输出 2.支持各路输入输出灵活切换 3.支持USB接口 4.支持网口 5.支持音频输出接口 6.支持serders

使用nvm安装node.js过程

今天Jade尝试安装nvm&#xff0c;并使用命令安装node.js但是碰到了一些问题&#xff0c;在此作为学习记录分享出来。希望可以留下深刻的印象&#xff1a; 1、概念了解 nvm----- (Node.js version manager)是一个命令行应用&#xff0c;可以协助您快速地 更新、安装、使用、卸载…

Flask SQLAlchemy 技术指南

文章目录 什么是 Flask SQLAlchemy&#xff1f;安装 Flask SQLAlchemy创建 Flask 应用和数据库模型添加和查询数据运行 Flask 应用总结**数据库迁移&#xff08;Database Migrations&#xff09;****复杂查询****关系模型****事务处理****性能优化****安全性****扩展功能** Fla…