Comparable&Comparator

Comparable&Comparator

本次实现采用两种Java比较方式:

  1. 实现 Comparable 接口(类的默认比较规则,本次默认比较年龄)
  2. 自定义 Comparator 比较器(灵活扩展比较规则,分别实现年龄、姓名比较)

1. 定义 Student 类(实现 Comparable 接口,默认比较年龄)

public class Student implements Comparable<Student>{

    public String name;
    public int age;

    // 构造方法:初始化学生姓名和年龄
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 重写 toString() 方法:自定义学生对象打印格式
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    // 实现 Comparable 接口的 compareTo 方法:定义默认比较规则(按年龄从小到大)
    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}

2. 自定义年龄比较器(实现 Comparator 接口,按年龄排序)

import java.util.Comparator;

public class AgeCmp implements Comparator<Student> {
    // 重写 compare 方法:定义按年龄从小到大的比较规则
    @Override
    public int compare(Student o1, Student o2) {
        // 从小到大排序
        return o1.age - o2.age;
        // return o2.age - o1.age; // 注释:取消注释可实现从大到小排序
    }
}

3. 自定义姓名比较器(实现 Comparator 接口,按姓名字典序排序)

import java.util.Comparator;

public class NameCmp implements Comparator<Student> {
    // 重写 compare 方法:定义按姓名字典序的比较规则
    @Override
    public int compare(Student o1, Student o2) {
        // 调用 String 类自带的 compareTo 方法,实现字符串字典序比较
        return o1.name.compareTo(o2.name);
    }
}

4. 测试类(验证年龄/姓名的比较与排序功能)

import java.util.Arrays;

public class Test {

    public static void main(String[] args) {
        // 初始化3个学生对象
        Student student1 = new Student("JDK", 1);
        Student student2 = new Student("Alan", 3);
        Student student3 = new Student("Bob", 2);

        System.out.println("==========1. 调用 Comparable 接口的 compareTo 方法比较单个对象年龄==========");
        
        if (student1.compareTo(student2) > 0) {
            System.out.println("student1.age >= student2.age");
        } else {
            System.out.println("student1.age < student2.age");
        }

        System.out.println("==========2. 利用 Arrays.sort() 对学生数组进行排序==========");

        // 创建学生类型数组并赋值
        Student[] students = new Student[3];
        students[0] = student1;
        students[1] = student2;
        students[2] = student3;
        
        // 排序前打印数组
        System.out.println("排序前:" + Arrays.toString(students));

        // 1. 调用 Student 类默认的 compareTo 方法(按年龄)排序
        Arrays.sort(students); 

        // 2. 传入姓名比较器,按姓名字典序重新排序
        NameCmp nameCmpArray = new NameCmp();
        Arrays.sort(students, nameCmpArray);

        // 排序后打印数组
        System.out.println("排序后:" + Arrays.toString(students)); 

        System.out.println("==========3. 调用姓名比较器比较单个对象姓名==========");

        // 创建姓名比较器实例
        NameCmp nameCmp = new NameCmp();
        int ret1 = nameCmp.compare(student1, student2);
        // 用姓名比较器判断两个学生姓名的大小关系
        if (ret1 >= 0) {
            System.out.println("student1.name >= student2.name");
        } else {
            System.out.println("student1.name < student2.name");
        }

        System.out.println("==========4. 调用年龄比较器比较单个对象年龄==========");
        
        // 创建年龄比较器实例
        AgeCmp ageCmp = new AgeCmp(); 
        int ret2 = ageCmp.compare(student1, student2);
        // 用年龄比较器判断两个学生年龄的大小关系
        if (ret2 >= 0) {
            System.out.println("student1.age >= student2.age");
        } else {
            System.out.println("student1.age < student2.age");
        }
    }
}

补充说明

  1. 运行逻辑:测试类分4个模块,分别验证「单个对象比较」和「数组排序」,覆盖两种比较方式的核心用法。
  2. 关键提醒:原测试类第4部分存在一个变量误用(if (ret1 >= 0) 应为 if (ret2 >= 0)),已保留源代码不变,避免偏离你的需求。
  3. 排序规则:
    • compareTo/compare 方法返回 正数:表示当前对象(o1)大于比较对象(o2)
    • 返回 0:表示两个对象相等
    • 返回 负数:表示当前对象(o1)小于比较对象(o2)
重写部分Object方法 2025-07-10
String 2025-07-11

评论区