Java基础二十二(对集合元素排序比较)

对集合元素排序比较

1. 使用 Comparable 接口实现默认排序

Comparable 是 Java 中的一个接口,用于定义对象之间的排序规则。

实现了 Comparable 接口的类可以比较其对象的大小(包装类都实现了该接口),从而可以在集合类(如 TreeSet、TreeMap 等)中进行排序和查找操作。这种排序被称为类的自然排序,类的 compareTo() 方法被称为它的自然比较方法。

java 复制代码
public interface Comparable<T> {
	int compareTo(T o);
}

compareTo() 方法的返回值有以下三种情况:

  • 返回负整数:表示当前对象小于传入对象。
  • 返回零:表示当前对象等于传入对象。
  • 返回正整数:表示当前对象大于传入对象。
  • T 是泛型的一种表现方式,表示一种类型。

示例1

学生类 Student 实现了 Comparable 接口,重写了 compareTo() 方法,通过比较总成绩实现对象之间的大小比较。

java 复制代码
public class Student implements Comparable{
    private String name;
    private int math;
    private int chinese;

    public Student(String name, int math, int chinese) {
        this.name = name;
        this.math = math;
        this.chinese = chinese;
    }

    public int getMath() {
        return math;
    }

    public int getChinese() {
        return chinese;
    }

    // 获取总成绩
    public int getTotal() {
        return math + chinese;
    }

    // 根据方法重写比较器
    @Override
    public int compareTo(Object o) throws RuntimeException {
        if (o instanceof Student student) {
            if (this.getTotal() > student.getTotal()) {
                return 1;
            } else if (this.getTotal() < student.getTotal()) {
                return -1;
            }
            // 比较姓名
            return this.name.compareTo(student.name);
        }
        throw new CompareException("类型不匹配");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", math=" + math +
                ", chinese=" + chinese +
                '}' + getTotal();
    }

    // 自定义异常
    class CompareException extends RuntimeException {
        public CompareException() {
            super();
        }

        public CompareException(String message) {
            super(message);
        }
    }
}
java 复制代码
public class ComparableExample {
    public static void main(String[] args) {
        Student[] stus = {
                new Student("张三", 23, 90),
                new Student("李四", 24, 80),
                new Student("王五", 23, 70),
                new Student("赵六", 24, 80),
                new Student("田七", 25, 50)
        };
        sort(stus);
        for (Student student : stus) {
            System.out.println(student.toString());
        }
    }

    private static void sort(Student[] students) {
        for (int i = 0; i < students.length - 1; i++) {
            for (int j = 0; j < students.length - 1 - i; j++) {
                if (students[j].compareTo(students[j + 1]) < 0) {
                    Student studentTemp = students[j];
                    students[j] = students[j + 1];
                    students[j + 1] = studentTemp;
                }
            }
        }
    }
}

输出

复制代码
Student{name='张三', math=23, chinese=90}113
Student{name='赵六', math=24, chinese=80}104
Student{name='李四', math=24, chinese=80}104
Student{name='王五', math=23, chinese=70}93
Student{name='田七', math=25, chinese=50}75

2. 使用 Comparator 接口实现比较器排序

Comparator 是 java 中的一个接口,用于定义对象之间的定制排序规则。

Comparable 接口不同,Comparator 接口允许在排序时使用独立于对象类的比较逻辑,因此可以在不休改对象类的情况下实现多种不同的排序方式,当使用了实现 Comparator 接口的比较器后,默认的 COmparable 比较器就不起作用了。

使用 Comparator 接口需要重写 compare() 方法,该方法的定义语法格式如下:

java 复制代码
public interface Comparator<T> {
	int compare(T o1, T o2);
	boolean equals(Object obj);
}

示例2

按照语文成绩排序

java 复制代码
import java.util.Arrays;
import java.util.Objects;

public class ComparableExample {
    public static void main(String[] args) {
        Student[] stus = {
                new Student("张三", 23, 90),
                new Student("李四", 24, 80),
                new Student("王五", 43, 70),
                new Student("赵六", 24, 80),
                new Student("田七", 25, 50)
        };
		// 使用 Arrsys.sort(),传入比较器,实现对多个对象比较
        ChineseComparator comparator = new ChineseComparator();
        Arrays.sort(stus, comparator);
        for (Student student : stus) {
            System.out.println(student.toString());
        }

		// 比较两个对象
//        int n = Objects.compare(stus[1], stus[3], comparator);
//        System.out.println(n);
    }
java 复制代码
package kfm.bases.SetDemo;

import java.util.Comparator;

public class ChineseComparator implements Comparator {
	// 按照语文成绩排序
    @Override
    public int compare(Object o1, Object o2) {
        if (o1 != null && o2 != null) {
            if (o1 instanceof Student student1 && o2 instanceof Student student2) {
                return student1.getChinese() - student2.getChinese();
            } else {
                throw new RuntimeException("数据类型异常");
            }
        } else {
            throw new RuntimeException("空指针异常");
        }
    }
}

输出:

复制代码
Student{name='田七', math=25, chinese=50}75
Student{name='王五', math=43, chinese=70}113
Student{name='李四', math=24, chinese=80}104
Student{name='赵六', math=24, chinese=80}104
Student{name='张三', math=23, chinese=90}113

compare() 方法用于在 Arrays 类调用 sort(比较对象数组, 比较器) 方法时,对两个对象进行比较大小。

相关推荐
Lionel_SSL2 小时前
《深入理解Java虚拟机》第三章读书笔记:垃圾回收机制与内存管理
java·开发语言·jvm
记得开心一点嘛2 小时前
手搓Springboot
java·spring boot·spring
老华带你飞3 小时前
租房平台|租房管理平台小程序系统|基于java的租房系统 设计与实现(源码+数据库+文档)
java·数据库·小程序·vue·论文·毕设·租房系统管理平台
独行soc3 小时前
2025年渗透测试面试题总结-66(题目+回答)
java·网络·python·安全·web安全·adb·渗透测试
脑子慢且灵3 小时前
[JavaWeb]模拟一个简易的Tomcat服务(Servlet注解)
java·后端·servlet·tomcat·intellij-idea·web
华仔啊4 小时前
SpringBoot 中 6 种数据脱敏方案,第 5 种太强了,支持深度递归!
java·后端
异常驯兽师5 小时前
Spring 中处理 HTTP 请求参数注解全解析
java·spring·http
连合机器人6 小时前
晨曦中的守望者:当科技为景区赋予温度
java·前端·科技
AD钙奶-lalala6 小时前
idea新建的项目new 没有java class选项
java·ide·intellij-idea
sheji34166 小时前
【开题答辩全过程】以 12306候补购票服务系统为例,包含答辩的问题和答案
java·eclipse