一、定制排序:java.util.Comparator 接口
强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序。
java.util.Comparator接口:
抽象方法:int compare(T o1, T o2)
是泛型,可以理解成 Object。
java.util.Comparator接口:
抽象方法:int compare(Object o1, Object o2)
说明:这个接口是代表 Java 中比较两个对象的大小标准。而且是一种“定制”比较的标准。
这个接口中没有规定如何比较两个对象的大小。
但是规定了:如果认为 o1 大于 o2,那么就返回正整数表示;
如果认为 o1 小于 o2,那么就返回负整数表示;
如果认为 o1 等于 o2,那么就返回0表示;
需求:声明一个学生类,实现 comparator 接口,来定制两个学生比较的具体实现方式
Demo:
学生类:
1 classStudent{2 privateString name;3 private intage;4 private intscore;5 public Student(String name, int age, intscore) {6 super();7 this.name =name;8 this.age =age;9 this.score =score;10 }11 publicStudent() {12 super();13 }14 publicString getName() {15 returnname;16 }17 public voidsetName(String name) {18 this.name =name;19 }20 public intgetAge() {21 returnage;22 }23 public void setAge(intage) {24 this.age =age;25 }26 public intgetScore() {27 returnscore;28 }29 public void setScore(intscore) {30 this.score =score;31 }32 @Override33 publicString toString() {34 return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";35 }36
37 }
View Code
测试类:
1 public classTestComparator {2 public static voidmain(String[] args) {3 Student s1 = new Student("小李子", 25, 89);4 Student s2 = new Student("小张字", 24, 99);5
6
7 AgeComparator c = newAgeComparator();8 if(c.compare(s1, s2) > 0){ //如果比较s1,s2的结果是正整数,说明s1>s2
9 System.out.println("s1 > s2的年龄");10 }else if(c.compare(s1, s2) <0){11 System.out.println("s1 < s2的年龄");12 }else{13 System.out.println("s1 = s2的年龄");14 }15
16
17 Student[] all = new Student[5];18 all[0] =s1;19 all[1] =s2;20 all[2] = new Student("张三",22,87);21 all[3] = new Student("李四",24,44);22 all[4] = new Student("王五",25,45);23
24 //Arrays工具类25 //Arrays.sort(all);
26
31 Arrays.sort(all, newAgeComparator());32
33 for (int i = 0; i < all.length; i++) {34 System.out.println(all[i]);35 }36 }37 }38
39 //实现Comparator接口,来定制两个学生比较的具体实现方式40 //例如:按照年龄比较
41 class AgeComparator implementsComparator{42
43 @Override44 public intcompare(Object o1, Object o2) {45 //(1)向下转型
46 Student s1 =(Student) o1;47 Student s2 =(Student) o2;48
49 //(2)开始比较
50 if(s1.getAge() >s2.getAge()){51 return 1;52 }else if(s1.getAge()
58 }
二、自然排序:java.lang.Comparable 接口
Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo(T t) 方法被称为它的自然比较方法。当前对象this与指定对象t比较“大小”,如果当前对象this大于指定对象t,则返回正整数,如果当前对象this小于指定对象t,则返回负整数,如果当前对象this等于指定对象t,则返回零。
实现Comparable接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
Comparable 的典型实现:
String:按照字符串中字符的Unicode值进行比较
Character:按照字符的Unicode值来进行比较
数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
Date、Time等:后面的日期时间比前面的日期时间大
java.lang.Comparable:自然比较,自然顺序
int compareTo(Object obj)
this 与 obj 对象比较,this > obj,返回正整数;
this 与 obj 对象比较,this < obj,返回负整数;
this 与 obj 对象比较,this = obj,返回0;
对于上面的案例来说,如果希望学生对象本身就具备比较大小的能力。可以使学生实现 Comparable 接口。
代码:
1 public classTestComparable {2 public static voidmain(String[] args) {3 Student s1 = new Student("小李子", 25, 89);4 Student s2 = new Student("小张字", 24, 99);5
6 //按成绩比较
7 if(s1.compareTo(s2)>0){8 System.out.println("s1 > s2成绩");9 }else if(s1.compareTo(s2)<0){10 System.out.println("s1 < s2成绩");11 }else{12 System.out.println("s1 = s2成绩");13 }14
15
16 }17 }18 class Student implementsComparable{19 privateString name;20 private intage;21 private intscore;22 public Student(String name, int age, intscore) {23 super();24 this.name =name;25 this.age =age;26 this.score =score;27 }28 publicStudent() {29 super();30 }31 publicString getName() {32 returnname;33 }34 public voidsetName(String name) {35 this.name =name;36 }37 public intgetAge() {38 returnage;39 }40 public void setAge(intage) {41 this.age =age;42 }43 public intgetScore() {44 returnscore;45 }46 public void setScore(intscore) {47 this.score =score;48 }49 @Override50 publicString toString() {51 return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";52 }53 @Override54 public intcompareTo(Object obj) {55 //this与obj比较,this和obj都是学生对象
56 Student other =(Student) obj;57 //例如:对于学生对象来说,最常用的是按成绩排名,那么我就可以把自然顺序定位成绩升序
58
64
65 return this.score -other.score;66 }67 }
总结:
Arrays的 sort 方法有两种:
(1)void sort(Object[] arr)
根据元素的自然顺序对指定对象数组按升序进行排序,数组中的所有元素必须实现 Comparable 接口。
(2)void sort(Object[] arr, Comparator c)
根据“指定比较器”产生的顺序对指定对象数组进行排序,数组中的所有元素都必须是通过“指定比较器”可相互比较的。