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