需求场景:对学生进行排序,每名学生有语文、数学、英语3门课程的成绩,排序规则:首先比总分,总分相同则依次比较 语文、数学、英语,若分数全部相同,则按照名字的字典序排序。
方法1. 实现Comparable接口
Student类实现Comparable接口,并实现该接口的compareTo()方法,然后调用 Collections.sort()对类型为Student的 list 排序。
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
List<Students> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
Students stu = new Students(scanner.next(), scanner.nextInt(), scanner.nextInt(), scanner.nextInt());
list.add(stu);
}
Collections.sort(list);
}
}
class Students implements Comparable<Students>{
String name;
int sc1;
int sc2;
int sc3;
int total;
int rank;
public Students(String na, int sc1, int sc2, int sc3){
this.name = na;
this.sc1 = sc1;
this.sc2 = sc2;
this.sc3 = sc3;
this.total = sc1 + sc2 + sc3;
}
@Override
public int compareTo(Students students) {
if(this.total == students.total){
if(this.sc1 == students.sc1){
if(this.sc2 == students.sc2){
if (this.sc3 == students.sc3) {
//名字按照字典序排序
return this.name.compareTo(students.name);
} else {
//降序排序,所以有负号
return -Integer.compare(this.sc3, students.sc3);
}
}else{
return -Integer.compare(this.sc2, students.sc2);
}
}else{
return -Integer.compare(this.sc1, students.sc1);
}
}else{
return -Integer.compare(this.total, students.total);
}
}
方法2. 使用Comparator比较器
直接调用 Collections.sort()方法对 list 排序,并在参数2处传入一个 Comparator,并重写它的 compare方法。
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
List<Student> list = new ArrayList<Student>();
for (int i = 0; i < n; i++) {
Student stu = new Student(scanner.next(), scanner.nextInt(), scanner.nextInt(), scanner.nextInt());
list.add(stu);
}
//排序
sortScore(list);
}
public static void sortScore(List<Student> list) {
//使用比较器Comparator对复杂类型的list进行排序
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student stu1, Student stu2) {
int sum1 = stu1.score1 + stu1.score2 + stu1.score3;
int sum2 = stu2.score1 + stu2.score2 + stu2.score3;
stu1.totalScore = sum1;
stu2.totalScore = sum2;
int sumDiff = sum1 - sum2;
if(sumDiff != 0){
return sumDiff < 0 ? 1 : -1;
}
else{
//比较第一科分数
int sc1Diff = stu1.score1 - stu2.score1;
if(sc1Diff != 0){
return sc1Diff < 0 ? 1 : -1;
}
else{
//比较第二科分数
int sc2Diff = stu1.score2 - stu2.score2;
if(sc2Diff != 0){
return sc2Diff < 0 ? 1 : -1;
}
else{
//比较第三科分数
int sc3Diff = stu1.score3 - stu2.score3;
if(sc3Diff != 0){
return sc3Diff < 0 ? 1 : -1;
}
}
}
}
//名字按照字典序排序
return stu1.name.compareTo(stu2.name);
}
});
}
}
class Student{
String name;
int score1;
int score2;
int score3;
int totalScore;
int rank;
public Student(String name, int score1, int score2, int score3){
this.name = name;
this.score1 = score1;
this.score2 = score2;
this.score3 = score3;
}
}
返回值和排序结果
排序默认是升序;
返回值:
负数,第一个参数排在前面,表明第一个参数比较小;
正数,第一个参数排在后面,表明第一个参数比较大;
0,第一个参数排在前面,表明第一个参数和第二个参数一样大。
想要结果降序排列,可以:
在 compare(int para1, int para2)方法 或者 compareTo(int para1, int para2)方法中,
return para1 < para2 ? 1 : -1; //para1比para2小时,返回1,排在后面,实现降序排列