普通排序
对于基础数据类型的排序,基本只是调用一下方法
如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