• Java 之 比较器( Comparator接口与 Comparable 接口)


    一、定制排序:java.util.Comparator 接口

      强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。

      当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序。

    java.util.Comparator<T>接口:
        抽象方法:int compare(T o1, T o2)
    

      <T> 是泛型,可以理解成 Object。

      java.util.Comparator接口:

        抽象方法:int compare(Object o1, Object o2)

      说明:这个接口是代表 Java 中比较两个对象的大小标准。而且是一种“定制”比较的标准。

         这个接口中没有规定如何比较两个对象的大小。

         但是规定了:如果认为 o1 大于 o2,那么就返回正整数表示;

               如果认为 o1 小于 o2,那么就返回负整数表示;

               如果认为 o1 等于 o2,那么就返回0表示;

      需求:声明一个学生类,实现 comparator 接口,来定制两个学生比较的具体实现方式

      Demo:

      学生类:

     1 class Student{
     2     private String name;
     3     private int age;
     4     private int score;
     5     public Student(String name, int age, int score) {
     6         super();
     7         this.name = name;
     8         this.age = age;
     9         this.score = score;
    10     }
    11     public Student() {
    12         super();
    13     }
    14     public String getName() {
    15         return name;
    16     }
    17     public void setName(String name) {
    18         this.name = name;
    19     }
    20     public int getAge() {
    21         return age;
    22     }
    23     public void setAge(int age) {
    24         this.age = age;
    25     }
    26     public int getScore() {
    27         return score;
    28     }
    29     public void setScore(int score) {
    30         this.score = score;
    31     }
    32     @Override
    33     public String toString() {
    34         return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
    35     }
    36     
    37 }
    View Code

      测试类:

     1 public class TestComparator {
     2     public static void main(String[] args) {
     3         Student s1 = new Student("小李子", 25, 89);
     4         Student s2 = new Student("小张字", 24, 99);
     5         
     6         
     7         AgeComparator c = new AgeComparator();
     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         /*
    27          * public static void sort(Object[] a, Comparator c)
    28          * 第一个形参:需要排序的数组,Object[]说明可以是任意类型的对象数组
    29          * 第二个形参:比较器对象     Comparator接口不能创建对象,只能传入实现类对象
    30          */
    31         Arrays.sort(all, new AgeComparator());
    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 implements Comparator{
    42 
    43     @Override
    44     public int compare(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() < s2.getAge()){
    53             return -1;
    54         }
    55         return 0;
    56     }
    57     
    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 class TestComparable {
     2     public static void main(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 implements Comparable{
    19     private String name;
    20     private int age;
    21     private int score;
    22     public Student(String name, int age, int score) {
    23         super();
    24         this.name = name;
    25         this.age = age;
    26         this.score = score;
    27     }
    28     public Student() {
    29         super();
    30     }
    31     public String getName() {
    32         return name;
    33     }
    34     public void setName(String name) {
    35         this.name = name;
    36     }
    37     public int getAge() {
    38         return age;
    39     }
    40     public void setAge(int age) {
    41         this.age = age;
    42     }
    43     public int getScore() {
    44         return score;
    45     }
    46     public void setScore(int score) {
    47         this.score = score;
    48     }
    49     @Override
    50     public String toString() {
    51         return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
    52     }
    53     @Override
    54     public int compareTo(Object obj) {
    55         //this与obj比较,this和obj都是学生对象
    56         Student other = (Student) obj;
    57         //例如:对于学生对象来说,最常用的是按成绩排名,那么我就可以把自然顺序定位成绩升序
    58 /*        if(this.score > other.score){
    59             return 1;
    60         }else if(this.score < other.score){
    61             return -1;
    62         }
    63         return 0;*/
    64         
    65         return this.score - other.score;
    66     }
    67 }

      总结:

        Arrays 的 sort 方法有两种:

       (1)void sort(Object[] arr)

           根据元素的自然顺序对指定对象数组按升序进行排序,数组中的所有元素必须实现 Comparable 接口

       (2)void sort(Object[] arr, Comparator c)

           根据“指定比较器”产生的顺序对指定对象数组进行排序,数组中的所有元素都必须是通过“指定比较器”可相互比较的。

  • 相关阅读:
    HTML5-拖拽
    POJ1182食物链(并查集)
    欧拉函数之HDU1286找新朋友
    Another kind of Fibonacce(矩阵快速幂,HDU3306)
    我的第一道java_A+B
    bestcoder#33 1002 快速幂取余+模拟乘,组合数学
    快速幂模版
    bestcoder#33 1001 高精度模拟
    poj2446_二分图
    poj3984_bfs+回溯路径
  • 原文地址:https://www.cnblogs.com/niujifei/p/11944983.html
Copyright © 2020-2023  润新知