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(比较对象数组, 比较器) 方法时,对两个对象进行比较大小。

相关推荐
骑士雄师12 分钟前
Java 泛型中级面试题及答案
java·开发语言·面试
.格子衫.6 小时前
Spring Boot 原理篇
java·spring boot·后端
多云几多6 小时前
Yudao单体项目 springboot Admin安全验证开启
java·spring boot·spring·springbootadmin
Jabes.yang8 小时前
Java求职面试实战:从Spring Boot到微服务架构的技术探讨
java·数据库·spring boot·微服务·面试·消息队列·互联网大厂
聪明的笨猪猪8 小时前
Java Redis “高可用 — 主从复制”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
兮动人9 小时前
Spring Bean耗时分析工具
java·后端·spring·bean耗时分析工具
MESSIR229 小时前
Spring IOC(控制反转)中常用注解
java·spring
摇滚侠9 小时前
Spring Boot 3零基础教程,Demo小结,笔记04
java·spring boot·笔记
笨手笨脚の10 小时前
设计模式-迭代器模式
java·设计模式·迭代器模式·行为型设计模式
spencer_tseng10 小时前
Eclipse 4.7 ADT (Android Development Tools For Eclipse)
android·java·eclipse