📅  最后修改于: 2023-12-03 15:24:32.119000             🧑  作者: Mango
在 Java 中,TreeSet 是一种基于红黑树实现的有序集合,它可以对元素进行排序。然而,对于用户自定义的对象,需要实现 Comparable 接口,重写 compareTo 方法来指定排序规则。本篇文章将介绍如何在 Java 中使用用户定义的对象对 TreeSet 进行排序。
首先,我们需要定义一个用户自定义的对象,比如一个学生类。然后,我们要让这个学生类实现 java.lang.Comparable 接口,重写 compareTo 方法。
public class Student implements Comparable<Student> {
private String name;
private int age;
private int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getScore() {
return score;
}
@Override
public int compareTo(Student otherStudent) {
int result = this.name.compareTo(otherStudent.name);
if (result == 0) {
result = Integer.compare(this.age, otherStudent.age);
if (result == 0) {
result = Integer.compare(this.score, otherStudent.score);
}
}
return result;
}
}
在 compareTo 方法中,我们首先按照学生姓名进行比较,如果姓名相同,则按照年龄比较,如果年龄也相同,则按照成绩比较。这样,我们就定义了一个基于姓名、年龄和成绩来比较两个学生对象的方法。
注意:compareTo 方法必须具有以下特性:
现在我们已经定义了一个实现了 Comparable 接口的学生类,可以使用 TreeSet 对学生对象进行排序了。下面是一个使用 TreeSet 实现排序的示例代码:
import java.util.*;
public class TreeSetExample {
public static void main(String[] args) {
Student[] students = new Student[] {
new Student("Tom", 18, 90),
new Student("Jerry", 20, 85),
new Student("Mike", 19, 88),
new Student("Tom", 20, 95),
new Student("Rick", 18, 85)
};
TreeSet<Student> treeSet = new TreeSet<>();
Collections.addAll(treeSet, students);
for (Student student : treeSet) {
System.out.printf("name: %s, age: %d, score: %d\n",
student.getName(), student.getAge(), student.getScore());
}
}
}
运行结果如下:
name: Jerry, age: 20, score: 85
name: Mike, age: 19, score: 88
name: Rick, age: 18, score: 85
name: Tom, age: 18, score: 90
name: Tom, age: 20, score: 95
可以看到,TreeSet 对学生对象按照我们定义的 compareTo 方法进行了排序,而且没有重复元素。
除了让学生类实现 Comparable 接口,我们也可以定义一个实现了 java.util.Comparator 接口的比较类来指定排序规则。Comparator 接口和 Comparable 接口的区别在于,Comparable 接口是让对象自己实现比较逻辑,而 Comparator 接口则是让第三方实现比较逻辑。如果我们要使用 Comparator 接口,需要在创建 TreeSet 对象时传入比较器:
TreeSet<Student> treeSet = new TreeSet<>(new StudentComparator());
如下是一个使用 Comparator 接口实现排序的示例代码:
import java.util.*;
public class ComparatorExample {
public static void main(String[] args) {
Student[] students = new Student[] {
new Student("Tom", 18, 90),
new Student("Jerry", 20, 85),
new Student("Mike", 19, 88),
new Student("Tom", 20, 95),
new Student("Rick", 18, 85)
};
TreeSet<Student> treeSet = new TreeSet<>(new StudentComparator());
Collections.addAll(treeSet, students);
for (Student student : treeSet) {
System.out.printf("name: %s, age: %d, score: %d\n",
student.getName(), student.getAge(), student.getScore());
}
}
}
class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student student1, Student student2) {
int result = Integer.compare(student1.getScore(), student2.getScore());
if (result == 0) {
result = Integer.compare(student1.getAge(), student2.getAge());
if (result == 0) {
result = student1.getName().compareTo(student2.getName());
}
}
return result;
}
}
运行结果如下:
name: Jerry, age: 20, score: 85
name: Rick, age: 18, score: 85
name: Mike, age: 19, score: 88
name: Tom, age: 18, score: 90
name: Tom, age: 20, score: 95
可以看到,TreeSet 对学生对象按照我们定义的 StudentComparator 进行了排序,而且没有重复元素。
Java 中的 TreeSet 可以对元素进行排序,但对于用户自定义的对象,需要实现 Comparable 接口,重写 compareTo 方法来指定排序规则。如果不想修改原有类的代码,也可以定义一个实现了 Comparator 接口的比较类来指定排序规则。使用 TreeSet 进行排序时需要注意 Comparable 和 Comparator 接口的特性,以及 null 值的处理。