首页 > 编程语言 >java的排序问题

java的排序问题

时间:2023-02-26 18:00:10浏览次数:32  
标签:java chinese int sum 问题 Student 排序 o2 math

普通排序

对于基础数据类型的排序,基本只是调用一下方法

如java的 

1 Arrays.sort(nums);

那么如何自定义排序规则呢?

自定义排序规则:

假设现在有这么个问题,有n个学生, 每个学生有一个数学成绩,有一个语文成绩, 

要求按照总分从高到低排序,分数一样,再按照数学成绩从低到高, 再一样则按照语文成绩从高到低。

这个问题该怎么解决呢?

对于java, 我们有两种方式,一种是自定义Comparator比较器, 另一种是类实现Comparable接口。

首先我们定义一个学生类:

 1 class Student {
 2     int math; // 数学成绩
 3     int chinese; // 语文成绩
 4     public Student(int math, int chinese) {
 5         this.math = math;
 6         this.chinese = chinese;
 7     }
 8 
 9     // 返回总成绩
10     public int sum() {
11         return this.math + this.chinese;
12     }
13 }

Comparator比较器:

自定义一个比较对象:

 

 1     public static Comparator<Student> cmp = new Comparator<Student>(){
 2 
 3         @Override
 4         public int compare(Student o1, Student o2) {
 5             if (o1.sum() == o2.sum()) {
 6                 if (o1.math == o2.math) {
 7                     return Integer.compare(o1.chinese, o2.chinese);
 8                 } else {
 9                     // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
10                     return o1.math > o2.math ? 1 : -1;
11                 }
12             } else {
13                 // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
14                 return o1.sum() < o2.sum() ? 1 : -1;
15             }
16         }
17     };

这个比较器接口中, 有一个compare方法, 方法返回0, 1, -1 三个值, 0代表相等, -1代表o1小于o2, 1代码o1大于o2。

 

根据我们的比较规则,在compare方法中返回对应的值。

有了这个比较器,那么就可以进行排序:

1 Arrays.sort(students, cmp); // students是学生对象数组,cmp是我们的比较器

当然,如果这个比较器只需要用一次,也可以用匿名内部类的方式,如下:

 1         Arrays.sort(students, new Comparator<Student>() {
 2             @Override
 3             public int compare(Student o1, Student o2) {
 4                 if (o1.sum() == o2.sum()) {
 5                     if (o1.math == o2.math) {
 6                         return Integer.compare(o1.chinese, o2.chinese);
 7                     } else {
 8                         // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
 9                         return o1.math > o2.math ? 1 : -1;
10                     }
11                 } else {
12                     // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
13                     return o1.sum() < o2.sum() ? 1 : -1;
14                 }
15                 }
16             });

完整代码如下:

 1 import java.util.Arrays;
 2 import java.util.Comparator;
 3 import java.util.Scanner;
 4 
 5 class Student {
 6     int math; // 数学成绩
 7     int chinese; // 语文成绩
 8     public Student(int math, int chinese) {
 9         this.math = math;
10         this.chinese = chinese;
11     }
12 
13     // 返回总成绩
14     public int sum() {
15         return this.math + this.chinese;
16     }
17 }
18 
19 public class Main {
20     public static void main(String[] args) {
21         Scanner in = new Scanner(System.in);
22         int n = in.nextInt();
23         Student[] students = new Student[n];
24         for (int i=0; i<n; i++) {
25             students[i] = new Student(in.nextInt(), in.nextInt());
26         }
27         Arrays.sort(students, new Comparator<Student>() {
28             @Override
29             public int compare(Student o1, Student o2) {
30                 if (o1.sum() == o2.sum()) {
31                     if (o1.math == o2.math) {
32                         return Integer.compare(o1.chinese, o2.chinese);
33                     } else {
34                         // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
35                         return o1.math > o2.math ? 1 : -1;
36                     }
37                 } else {
38                     // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
39                     return o1.sum() < o2.sum() ? 1 : -1;
40                 }
41                 }
42             });
43         for(int i=0; i<n; i++) {
44             System.out.printf("%d  %d\n", students[i].math, students[i].chinese);
45         }
46     }
47 }

 

第二种方式: 类实现Comparable接口

这种方式是在学生类中实现Comparable接口, 这样这个类的对象就可以进行比较了, 从而不需要在sort方法中传比较器

以下是Student类的实现:

 

 1 class Student implements Comparable{
 2     int math; // 数学成绩
 3     int chinese; // 语文成绩
 4     public Student(int math, int chinese) {
 5         this.math = math;
 6         this.chinese = chinese;
 7     }
 8 
 9     // 返回总成绩
10     public int sum() {
11         return this.math + this.chinese;
12     }
13 
14     @Override
15     public int compareTo(Object o) {
16         Student other = (Student) o; // 先对o进行转型为Student对象
17         if (this.sum() == other.sum()) {
18             if (this.math == other.math) {
19                 return Integer.compare(this.chinese, other.chinese);
20             } else {
21                 // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
22                 return this.math > other.math ? 1 : -1;
23             }
24         } else {
25             // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
26             return this.sum() < other.sum() ? 1 : -1;
27         }
28     }
29 }

接下来排序,就和基本数据类型排序一样了, 不需要传入比较器。

Arrays.sort(students);

完整代码如下:

 1 import java.util.Arrays;
 2 import java.util.Comparator;
 3 import java.util.Scanner;
 4 
 5 class Student implements Comparable{
 6     int math; // 数学成绩
 7     int chinese; // 语文成绩
 8     public Student(int math, int chinese) {
 9         this.math = math;
10         this.chinese = chinese;
11     }
12 
13     // 返回总成绩
14     public int sum() {
15         return this.math + this.chinese;
16     }
17 
18     @Override
19     public int compareTo(Object o) {
20         Student other = (Student) o; // 先对o进行转型为Student对象
21         if (this.sum() == other.sum()) {
22             if (this.math == other.math) {
23                 return Integer.compare(this.chinese, other.chinese);
24             } else {
25                 // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
26                 return this.math > other.math ? 1 : -1;
27             }
28         } else {
29             // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
30             return this.sum() < other.sum() ? 1 : -1;
31         }
32     }
33 }
34 
35 public class Main {
36     public static void main(String[] args) {
37         Scanner in = new Scanner(System.in);
38         int n = in.nextInt();
39         Student[] students = new Student[n];
40         for (int i=0; i<n; i++) {
41             students[i] = new Student(in.nextInt(), in.nextInt());
42         }
43         Arrays.sort(students);
44         for(int i=0; i<n; i++) {
45             System.out.printf("%d  %d\n", students[i].math, students[i].chinese);
46         }
47     }
48 }

总结:

1. Java里面数组排序是用Arrays.sort 方法

2. 对于基本数据类型可以直接使用进行排序, 但遵循的是默认的大小比较。

3. 如果要自定义排序规则, 或者对对象数组进行排序, 则可以有两种方式

4. 单独定义一个比较器对象Comparator,将排序规则写在compare方法中, 调用sort方法时,传入这个比较器

5. 对于类,可以实现Comparable接口,重写compareTo方法, 这样这个类对象的数组进行排序时,不需要传入比较器,会用类中实现的CompareTo方法进行比较,从而排序。

6. 如果一个类实现了Comparable接口, 同时排序时又传入了一个比较器, 那么优先使用传入的比较器进行排序。

    比如我们的Integer等类,都是实现了Comparable接口的, 但你想用自己的规则排序,还是可以创建一个Comparator比较器,排序时传入sort方法中

 

 

 

标签:java,chinese,int,sum,问题,Student,排序,o2,math
From: https://www.cnblogs.com/QWZeng/p/17157156.html

相关文章