Java基础语法之对象的比较方式

 更新时间:2026年02月02日 10:52:32   作者:吞吞吐吐大魔王  
文章介绍了Java中自定义类类型的比较大小的三种方式:覆写基类的equals方法、基于Comparable接口的比较、基于Comparator接口自定义比较器的比较,每种方式都有其适用场景和局限性

1. 引入

基本类型可以直接比较大小,但是我们自定义的类类型可能就无法比较,如果自定义类的类型本身有多个属性的话,那么是以什么样的方式去比较这个类型对象的大小呢?

对于上述自定义的类类型的比较大小,我们有以下三种处理方式:

  • 覆盖基类的 equals 方法
  • 基于 Comparable 接口类的比较
  • 基于比较器比较

2. 方法一:覆写基类的 equals

2.1 介绍

对于自定义的类型,都默认继承了 Object 类,而 Object 类中提供了 equals 方法。

故我们可以使用 equals 方法去判断两个对象是不是相等。但是并不是任何情况都适用,下面为 Object 类中 equals 方法的定义

我们知道对于引用类型,用 == 号比较的其实是引用变量的地址,所以即使两个对象的值相等,但是由于地址不同所以结果也可能是错的,并且还由于自定义类中的属性不为1,所以不重写基类的 equals 方法的话,是无法正确比较对象的。

2.2 覆写 equals 方法的规则

  • 如果指向同一个对象,则返回 true
  • 如果传入的值为 null,则返回 false
  • 如果传入的对象类型不是自定义类或其子类,则返回 false
  • 最后比较对象的各个属性,如果是基本类型,则可以直接用 == 比较;如果是引用类型,则使用 equals 方法比较

2.3 实现代码

以下用自定义的 Student 类为例,重写其基类的 equals 方法

class Student{
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public boolean equals(Object o){
        if(this==o){
            return true;
        }
        if(o==null || !(o instanceof Student)){
            return false;
        }
        Student c=(Student)o;
        return this.name.equals(c.name) && this.age==c.age;
    }
}

2.4 局限性

覆写基类 equals 的方法虽然可以使自定义的类被比较,但是该方法只能进行相等和不相等的比较,不能按照大于或小于的方式进行比较。

3. 方法二:基于 Comparable 接口的比较

3.1 介绍

该方法在 解析 Java 的多态、抽象类和接口 这章介绍过了,有兴趣了解的 uu 可以去那篇文章里面看看

注意:

Comparable 是 java.lang 中的接口类,可以直接使用。

3.2 使用方法

  • 先让自定义的类继承 Comparable 接口
  • 再根据我们要以自定义类的哪个属性去比较,来重写 Comparable 类中的 compareTo 方法

3.3 实现代码

以下用自定义的 Student 类为例,以 name 为我们要比较的属性

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

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public int compareTo(Student o){
        return  this.name.compareTo(o.name);
    }
}

3.4 局限性

该方法虽然可以让不同对象根据某一个属性来比较大小,但是当我们确定好了以哪一个属性来比较对象的话,那么当我们想要使用另一个属性比较对象时,则需要修改重写 compareTo 方法

4. 方法三:基于 Comparator 接口,自定义比较器的比较

4.1 介绍

该方法在 解析 Java 的多态、抽象类和接口 这章介绍过了,有兴趣了解的 uu 可以去那篇文章里面看看

注意

Comparator 是 java.util 包中的泛型接口类,使用时必须导入对应的包。

4.2 使用方法

  • 我们选择一个自定义类中要比较的属性,可以再定义一个类(即比较器),继承于 Comparator 接口
  • 在该接口中,重写 Comparator 接口的 compare 方法,该方法重写的就是对这个属性比较的规则
  • 使用时我们就使用 compare 方法,

4.3 实现代码

以下用自定义的 Student 类为例,分别以 age、name 为我们要比较的属性来构造比较器

class Student{
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
// 以 Student 类中的 name 属性构造比较器
class NameComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2){
        return o1.name.compareTo(o2.name);
    }
}
// 以 Student 类中的 age 属性构造比较器
class AgeComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2){
        return o1.age-o2.age;
    }
}

使用比较器来进行比较

public class TestDemo{
    public static void main(String[] args){
        Student s1=new Student("Tom",18);
        Student s2=new Student("Alen",25);
        // 以 name 的大小来比较
        NameComparator nameComparator = new NameComparator();
        System.out.println(nameComparator.compare(s1,s2));
        // 以 age 的大小来比较
        AgeComparator ageComparator = new AgeComparator();
        System.out.println(ageComparator.compare(s1,s2));
    }
}
// 结果为:19 和 -7

5. 三种方式对比

覆写的方法说明
Object.equals因为所有类都是继承自 Object 的,所以直接覆写即可,但是只能比较相等于不相等,不能比较大于或小于
Comparable.compareTo需要手动实现接口,侵入性较强。一旦实现,每次用该类都有指定的顺序,属于内部顺序。但如果要更换比较的方式,则要修改 comparaTo 方法
Comparator.compare需要实现一个比较器,对待比较类的侵入性较弱。每次使用,都要确定比较器

6. 总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java中RocketMQ的流量削峰详解

    Java中RocketMQ的流量削峰详解

    这篇文章主要介绍了Java中RocketMQ的流量削峰详解,MQ的主要特点为解耦、异步、削峰,该文章主要记录与分享个人在实际项目中的RocketMQ削峰用法,用于减少数据库压力的业务场景,需要的朋友可以参考下
    2023-09-09
  • java随机事件分发器示例

    java随机事件分发器示例

    这篇文章主要介绍了java随机事件分发器示例,需要的朋友可以参考下,功能需求和代码实现在下面
    2014-03-03
  • SpringBoot调用Poi-tl实现渲染数据并生成Word文档

    SpringBoot调用Poi-tl实现渲染数据并生成Word文档

    这篇文章主要为大家详细介绍了SpringBoot如何调用Poi-tl实现渲染数据并生成Word文档,文中的示例代码讲解详细,有需要的小伙伴可以了解下
    2023-09-09
  • SpringBoot的内嵌和外置tomcat的实现方式

    SpringBoot的内嵌和外置tomcat的实现方式

    本文主要介绍了在Spring Boot中定制和修改Servlet容器的配置,包括内嵌式和外置式Servlet容器的配置方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • mybatis-plus配置拦截器实现sql完整打印的代码设计

    mybatis-plus配置拦截器实现sql完整打印的代码设计

    在使用mybatis-plus(mybatis)的时候,往往需要打印完整的sql语句,然而输出的日志不是很理想,因为sql语句中的关键字段信息都是用?来代替的,所以本文分享了一下自己写了一个拦截器实现了sql完整的打印,需要的朋友可以参考下
    2024-06-06
  • Java实现一个小说采集程序的简单实例

    Java实现一个小说采集程序的简单实例

    下面小编就为大家带来一篇Java实现一个小说采集程序的简单实例。小编觉得挺不错的, 现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • java实现钉钉机器人消息推送的示例代码

    java实现钉钉机器人消息推送的示例代码

    这篇文章主要介绍了java实现钉钉机器人消息推送的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • Java 实战项目之家居购物商城系统详解流程

    Java 实战项目之家居购物商城系统详解流程

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用Java实现一个家居购物商城系统,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • SpringMVC实现表单验证功能详解

    SpringMVC实现表单验证功能详解

    这篇文章主要为大家详细介绍了SpringMVC 表单验证的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • springboot集成redis启动报错问题的解决方式

    springboot集成redis启动报错问题的解决方式

    这篇文章主要介绍了springboot集成redis启动报错问题的解决方式,从错误信息上看缺少pool2相关包,查询资料发现当redis客户端选择Lettuce时候需要增加:commons-pool2
    添加引用,重启服务,需要的朋友可以参考下
    2023-11-11

最新评论