[ Java SE] 对象的比较

news2024/12/22 2:28:04

🎉🎉🎉点进来你就是我的人了
博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!

人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习!

欢迎志同道合的朋友一起加油喔🦾🦾🦾
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个🐒嘿嘿
谢谢你这么帅气美丽还给我点赞!比个心


目录

1.基本类型的比较

2.对象(自定义类型)的比较

3.三种比较方法

1.重写基类(Object)中的equals方法

2.基于Comparble接口类的比较

3.基于比较器的比较

3.1 Comparable和Comparator

3.2 重写Comparator中的compare方法

4.三种方式的对比



1.基本类型的比较

我们知道基本类型可以直接比较大小,例如下面的代码:

public class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(a > b);
        System.out.println(a < b);
        System.out.println(a == b);
        System.out.println("======");
        char c1 = 'a';
        char c2 = 'b';
        System.out.println(c1 > c2);
        System.out.println(c1 < c2);
        System.out.println(c1 == c2);
    }
}

运行结果如下,从结果中可以看出这些数据可以直接比较。
在这里插入图片描述
那么在这里我要问一下,对象可以直接进行比较么?为什么呢?

2.对象(自定义类型)的比较

结合上面可以看出,基本类型是可以直接进行比较的,下面我将写一个对象进行比较的示例,我们来看一下能否运行成功。

class People {
    public int age;
    public String name;

    public People(int age, String name) {
        this.age = age;
        this.name = name;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        People p1 = new People(18,"zhangsan");
        People p2 = new People(20,"lisi");
        System.out.println(p1 > p2);//编译错误
        //在IDEA上这里其实已经标红报错啦
        System.out.println(p1 < p2);//编译错误
        System.out.println(p1 == p2);//编译成功
    }
}

解读代码
p1 == p2 编译成功,因为其指向的是两个不同的对象,对于用户实现自定义类型,都默认继承自Object类,而Object类中提供了equal方法,该方法的比较规则是:没有比较引用变量及引用对象的内容,而是直接比较引用变量的地址,所以可以编译成功;下图可以看出其直接比较的是两个引用变量的地址。 

在这里插入图片描述

p1 > p2 及 p1 < p2 不能编译成功,是因为Java中引用类型的变量不能直接按照 > 或者 < 方式进行比较,也可以这样想,编译器无法知道你是按照年龄来进行比较还是按照姓名来进行比较。

那么有些时候我们就是要比较对象中的内容,例如向优先级队列中插入某个对象时,需要按照对象中的内容来调整堆,这时候我们就需要来比较对象中的内容,该如何实现呢?下面的内容便是解决这个问题的三种方式,极其重要!!!

3.三种比较方法

1.重写基类(Object)中的equals方法

下面的代码便是一般覆写equals的套路,这里需要注意一下几点,代码中也进行了注释。
1.如果指向同一个对象,返回true;
2.如果是null,返回false;
3.如果传入的对象类型不是People,返回false;
4.按照类的实现目标来进行比较,例如下面的代码只要是年龄和姓名一样,就认为相同。

 缺点
覆写基类equal方式虽然可以比较,但只能按照相等进行比较,不能按照大于、小于的方式来进行比较。

class People {
    public int age;
    public String name;

    public People(int age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        //自己和自己比较
        if (this == obj) {
            return true;
        }
        //如果obj是null对象,或者不是People的子类
        if (obj == null || obj instanceof People) {
            return false;
        }
        //注意基本类型可以直接比较,但引用类型最好调用equal方法
        People p = (People) obj;
        return age == p.age && name.equals(p.name);
    }
}

2.基于Comparble接口类的比较

Comparble是JDK提供的泛型的比较接口类,源码如下:

public interface Comparable<E> {
        int compareTo(E o);
    }

说明:
" < 0" :表示this指向的对象小于o指向的对象;
" == 0":表示this指向的对象等于o指向的对象;
" > 0":表示this指向的对象等于o指向的对象。
示例:
对于用户自定义类型,如果要按照大小与方式进行比较时,在定义类时,实现Comparable接口即可,然后再类中重写compareTo方法。

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

    public People(int age, String name) {
        this.age = age;
        this.name = name;
    }
    //这里我们根据数值进行比较,不管姓名
    //这里认为null是最小的
    @Override
    public int compareTo(People o) {
        if (o == null) {
            return 1;
        }
        return age - o.age;
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        People p1 = new People(18,"zhangsan");
        People p2 = new People(20,"lisi");
        People o = new People(18,"lisi");
        System.out.println(p1.compareTo(o));
        System.out.println(p1.compareTo(p2));
        System.out.println(p2.compareTo(p1));
    }
}

运行结果:
" == 0 ",表示相等;
" < 0 ",表示p1比较小;
" > 0 ",表示p2比较大;

在这里插入图片描述

实现了comparaTo()方法使用age为标准升序排序。也可以以name为标准排序,或者其他自定义的比较依据。

但是当Student已经实现了以age为依据从小到大排序后,我们又想以name为依据排序,在这个简单的程序中可以直接将return this.age-o.age变为return this.name.compareTo(o.name)(name为String对象)。

但是这样修改类结构会显得十分麻烦,万一在以后的程序中遇到的是别人封装好的类不能直接改类结构又该怎么办。

有没有其他方便的比较方法,实现对象的大小比较。办法是有的,那就是实现Comparator接口。

3.基于比较器的比较

3.1 Comparable和Comparator

在学习比较器方式之前,需要区分一下Comparable和Comparator,不要混淆。

  1. Comparable是一个排序接口,也可以认为是一个内比较器,如果一个类实现了Comparable接口,就意味着这个类可以进行排序比较,例如上面写的代码中进行年龄的比较;

当该对象确定以什么属性进行比较之后就固定了,万一在以后的程序中遇到的是别人封装好的类不能直接改类结构就很麻烦,所以这种写法不太灵活,

  1. Comparator也是一个比较器,也可以认为是一个外比较器,例如我们需要对People类的年龄进行比较,People类中有两个属性:年龄(age)和姓名(name),但是People这个类是别人写好的,但是里面并没有Comparable接口,在不允许改变源代码的情况写,便可以使用Comparator接口,覆写方式如下。

使用 Comparator ,重新创建一个类或者使用内部类来实现 Comparator 接口,不需要修改待比较类的代码.

按照比较器方式进行比较,实现Comparator接口:

public interface Comparator<T> {
        int compare(T o1,T o2);
    }

说明
" < 0 ":表示o1指向的对象小于o2指向的对象;
" == 0 ":表示o1指向的对象等于o2指向的对象;
" > 0 ":表示o1指向的对象大于o2指向的对象。

3.2 重写Comparator中的compare方法

示例如下:

class People {
    public int age;
    public String name;

    public People(int age, String name) {
        this.age = age;
        this.name = name;
    }
}
class PeopleComparator implements Comparator<People> {
    @Override
    public int compare(People o1,People o2) {
        if(o1 == o2) {
            return 0;
        }
        if(o1 == null) {
            return -1;
        }
        if(o2 == null) {
            return 1;
        }
        return o1.age - o2.age;
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        People p1 = new People(18,"zhangsan");
        People p2 = new People(20,"lisi");
        People o = new People(18,"lisi");
        //定义比较器对象
        PeopleComparator cmptor = new PeopleComparator();
        //使用比较器对象进行比较
        System.out.println(cmptor.compare(p1,o));
        System.out.println(cmptor.compare(p1,p2));
        System.out.println(cmptor.compare(p2,p1));
    }
}

运行结果:
在这里插入图片描述
" == 0 ",表示相等;
" < 0 ",表示p1比较小;
" > 0 ",表示p2比较大;

4.三种方式的对比

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Postgres逻辑复制详解

逻辑复制 逻辑复制&#xff08;Logical Replication&#xff09;&#xff0c;是一种根据数据对象的 复制标识&#xff08;Replica Identity&#xff09;&#xff08;通常是主键&#xff09;复制数据对象及其变化的方法。 逻辑复制 这个术语与 物理复制相对应&#xff0c;物理…

不得不说的结构型模式-适配器模式

适配器模式&#xff08;Adapter Pattern&#xff09;是结构型模式之一&#xff0c;它将一个类的接口转换成客户希望的另一个接口&#xff0c;从而使原本由于接口不兼容而不能一起工作的类能够协同工作。适配器模式包括对象适配器和类适配器两种实现方式。 在对象适配器中&#…

Ae 入门系列之十:效果和动画预设

Ae 中提供了丰富的效果 Effects和动画预设 Animation Presets&#xff0c;可以轻松、快速地创建出各种酷炫的动画。 ◆ ◆ ◆ 效果 添加效果 方法一&#xff1a;先选中一个或多个图层&#xff0c;然后在Ae菜单&#xff1a;效果 Effect中找到并添加需要的效果。 方法二&#x…

什么是gpt一4-如何用上gpt-4

怎么使用gpt-4 目前GPT-4还未正式发布或公开&#xff0c;因此也没有详细的对接说明。但是我们可以根据GPT-4的前身GPT-3的应用经验&#xff0c;以及GPT-4的预期功能推测一些可能的使用步骤&#xff1a; 选择适合的GPT-4实现技术&#xff1a;GPT-4可能有不同的实现技术&#xff…

Allegro PCB后处理

Allegro PCB后处理&#xff0c;主要是完成线路设计以后&#xff0c;输出生产文件之前的处理。这是看教程做的记录&#xff0c;方便以后自己参考。 教程&#xff1a; [小哥Cadence Allegro 132讲字幕版PCB视频教程]_哔哩哔哩_bilibili 感觉关键是多看右边Options菜单&#xff0…

nodejs+python+php+springboot+vue 校园快递代取配送系统

管理员的主要功能有&#xff1a; 1.管理员输入账户登陆后台 2.个人中心&#xff1a;管理员修改密码和账户信息 3.用户管理&#xff1a;对注册的用户信息进行删除&#xff0c;查询&#xff0c;添加&#xff0c;修改 4.配送员管理&#xff1a;对配送员信息进行添加&#xff0c;修…

力扣刷题——移除元素

1、移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中…

【模拟IC】版图的基础操作和基础知识总结(1)

今天总结一下在画版图使用的基本操作和遇到的问题及解决方法。# 一、基本操作 &#xff08;1&#xff09;首先是使用layout XL的优势是可以对应原理图的器件&#xff0c;这样方便我们画版图。 &#xff08;2&#xff09;快捷键的操作&#xff1a; F 进行整体版图的居中 K 就是…

忙碌中也要记得休息,这两款好玩的游戏推荐给你

第一款&#xff1a;古墓丽影9年度版 《古墓丽影9》&#xff08;原名Tomb Raider&#xff09;是由水晶动力开发&#xff0c;史克威尔艾尼克斯发行的动作冒险游戏。 它于 2013 年发布。续集是古墓丽影崛起和古墓丽影暗影。 本作的重点是新版劳拉&#xff08;Lara Croft&#xf…

关于xilinx使用PCIE实现FPGA的部分重配置实现(MCAP)

平台&#xff1a;vivado21018.3 芯片&#xff1a;xcku115-flva1517-2-i (active) 本文官方文档&#xff1a;Xilinx_Answer_64761_Ultrascale_Devices 本文驱动下载地址&#xff1a;64761 - Bitstream Loading across the PCI Express Link in UltraScale and UltraScale Dev…

会话分享支持指定读写权限,网络设备支持账号切换、账号改密等自动化操作,JumpServer堡垒机v3.2.0发布

2023年4月24日&#xff0c;JumpServer开源堡垒机正式发布v3.2.0版本。在这一版本中&#xff0c;会话分享支持指定读写权限&#xff0c;让会话分享更加安全可靠。账号收集支持自动同步功能&#xff0c;并支持通过账号模版功能批量添加资产账号&#xff0c;同时账号切换功能新增支…

IT人员选择光缆的五大原因

基于铜和光纤的信号都会受到衰减&#xff0c;或者波形信号随着距离的推移而减弱。然而&#xff0c;光纤电缆可以在更长的距离上传输数据。事实上&#xff0c;差异是巨大的。 当构建需要长距离、高速和/或高带宽连接的网络时&#xff0c;毫无疑问&#xff1a;光纤电缆会赢得胜利…

使用ChatGPT完成程序开发——目标:不写一行代码完成图像识别并点击

本文作为一个使用AI开发的思路&#xff0c;让更多的人可以利用AI完成一些简单的程序&#xff0c;文中使用的是国内镜像GTP3.5 源码: GitHub - kasimshi/testCV: AI编写的OpenCV图像识别例子 GTP镜像: 知汇 对AI描述我们要做的功能&#xff0c;让它给给初步的思路和方向 作为新…

opencv-python视频分析与目标跟踪

目录 光流 目标跟踪 一、光流 使用OpenCV光流分析&#xff0c;跟踪蚂蚁的轨迹&#xff1a; 代码实现&#xff1a; import numpy as np import cv2if __name__ __main__:cap cv2.VideoCapture(ant.mp4)# ShiTomasi 角点检测参数feature_params dict(maxCorners100,quali…

ConcurrentHashMap底层实现原理

ConcurrentHashMap底层实现原理 ConcurrentHashMap的整体架构ConcurrentHashMap的基本功能ConcurrentHashMap在性能方面的优化 ConcurrentHashMap的整体架构 1.8中的存储结构&#xff1a; 它是由数组、单向链表、红黑树组成的。 当们去初始化一个ConcurrentHashMap实例的时候…

【工具】FFmpeg|超大视频本地有损压缩,500MB变5MB(支持 Windows、Linux、macOS)

参考&#xff1a; 如何将一分钟长的1080p视频压缩至5MB以内&#xff1f;-知乎-滔滔清风近期HEVC扩展备用安装方法-B站-悲剧天下 总共三个步骤&#xff0c;安装FFmpeg、运行指令、打开视频。 亲测 500MB 变 5MB。 1 安装FFmpeg 对于不需要看教程可以自行完成安装的同学们&…

哪款手持洗地机更好用?好用的手持洗地机分享

家居卫生清洁对于每个家庭来说都是必不可少的事情&#xff0c;尤其是地面清洁更是需要重视。传统的清洁方法需要频繁更换工具才能完成吸、拖、吸的清洁步骤&#xff0c;而这个过程费时费力且效果并不尽如人意。然而&#xff0c;洗地机的出现完美地解决了这一问题&#xff0c;将…

【C++进阶之路】初始C++语法(下)

文章目录 一.引用1.基本概念2.使用场景函数参数函数返回值 3.优点4.指针与引用的区别 二.内联函数引入1.默认设置2.建议3.声明与定义&#xff08;不同文件&#xff09;add.cppadd.htest.cpp 三.auto1.必须有初始值2.只能确定一个类型3.auto可以为类型的一部分4.函数参数和自定义…

Ubuntu20.04部署YOLOv5

目录 前言一、环境配置1 显卡驱动安装1.1 卸载显卡驱动1.2 准备工作1.3 驱动安装1.4 验证 2 CUDA安装2.1 准备工作2.2 CUDA下载2.3 CUDA安装2.4 配置环境变量2.5 验证2.6 小结 3 cuDNN安装3.1 cuDNN下载3.2 cuDNN安装3.3 小结 4 TensorRT安装4.1 TensorRT下载4.2 TensorRT安装4…

UOS-----本地YUM源配置

1. cd /etc/apt/sources.list.d/ 将文件中的两个list配置文件内容注释掉&#xff0c;并保存 2. cd /etc/apt/ vi sources.list 将配置文件内容注释 3. cd /etc/apt/sources.list.d/ vi local.list (创建一个新的list文件&#xff0c;作为本地yum配置文件) 添…