java 比对两对象大小 重写 comparator

经典接口

java.lang.Comparable

引用数据类型是不能直接使用比较运算符来比较大小。基本数据类型的数据(除boolean类型外)需要比较大小,用运算符比较就可以了。

java给所有引用数据类型的大小比较,指定了一个标准接口,就是java.lang.Comparable接口:

java 复制代码
package java.lang;

public interface Comparable {
  int compareTo(Object obj);
}

想要使得我们某个类的对象可以比较大小,怎么做呢?步骤:

第一步:哪个类的对象要比较大小,哪个类就实现java.lang.Comparable接口,并重写方法

  • 方法体就是你要如何比较当前对象指定的另一个对象的大小

第二步:对象比较大小时,通过对象调用compareTo方法,根据方法的返回值决定谁大谁小。

  • this对象(调用compareTo方法的对象)减 指定对象 (传入 compareTo()的参数对象)大于0,返回正整数。

  • this对象(调用compareTo方法的对象)减 指定对象(传入compareTo()的参数对象)小于0,返回负整数。

  • this对象(调用compareTo方法的对象)减 指定对象(传入compareTo()参数对象)等于0,返回零


新建个包c_interface

新建类Student:

java 复制代码
public class Student implements Comparable {
  private String name;
  private int score;
  
  public Student() {
  }
  
  public Student(String name, int score) {
    this.name = name;
    this.score = score;
  }
  
  public String getName() {
    return name;
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
  public String getScore() {
    return score;
  }
  
  public void setScore(String score) {
    this.score = score;
  }
  
  @Override
  public String toString() {
    return "Student{" +
    "name='" + name + '\'' +
    ", score=" + score +
    '}';
  }
  
  /*
    this:代表students[i]
    o:代表students[i+1]
    
    如果students[i].getScore()-students[i+1].getScore()>0,证明数组中的前面一个对象比后面一个对象的分数高
  */
  @Override
  public int compareTo(Object o) {
    // return this.getScore() - o.getScore(); 发现o不能getScore(),因为o是Object类型,所以需要向下转型。
    
    Student s = (Student) o;
    return this.getScore() - s.getScore();
  }
}

创建一个测试类

java 复制代码
public class Test01 {
  public static void main(String[] args) {
    // 创建一个数组
    Student[] students = new Student[3];
    Student s1 = new Student("张三", 100);
    Student s2 = new Student("李四", 60);
    Student s3 = new Student("王五", 80);
    students[0] = s1;
    students[1] = s2;
    students[2] = s3;
    
    // 冒泡排序
    for (int j = 0; j < students.length - 1; j++) {
      for (int i = 0; i < students.length - 1 - j; j++) {
        // 如果students[i]比students[i+1]大,就排序换位置
        if (students[i].compareTo(students[i+1]) > 0) {
        
          Student temp = students[i];
          students[i] = students[i+1];
          students[i+1] = temp;
        }
      }
    }
    
    //遍历 students.fori
    for (int i = 0; i < students.length; i++) {
      System.out.println(students[i]);
    }
   
   
    // 然后输出来后,就是按分数从小到大的对象进行排序了
  }
}

java.util.Comparator

思考:

(1)、如果一个类,没有实现Comparable接口,而这个类你又不方便修改(例如,一些第三方的类,你只有.class文件,没有源文件),那么这样类的对象也要比较大小怎么办?

(2)、如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?

JDK在设计类库之初,也考虑到这种情况了,所以又增加了一个java.util.Comparator接口。

java 复制代码
package java.util;

public interface Comparator {
  int compare(Object o1, Object o2);
}

那么我们想要比较某个类的两个对象的大小,怎么做呢?步骤:

第一步:编写一个类,我们称之为比较器类型,实现java.util.Comparator接口,并重写方法。

  • 方法体就是你要如何指定的两个对象的大小

第二步;比较大小时,通过比较器类型的对象调用compare()方法,将要比较大小的两个对象作为compare方法的实参传入,根据方法的返回值决定谁大谁小。

  • o1对象减o2大于0返回正整数
  • o1对象减o2小于0返回负整数
  • o1对象减o2等于0返回零

新建发一个包d_interface

// Student.java

java 复制代码
public class Student implements Comparable {
  private String name;
  private int score;
  
  public Student() {
  }
  
  public Student(String name, int score) {
    this.name = name;
    this.score = score;
  }
  
  public String getName() { return name; }
  
  public void setName(String name) {
    this.name = name;
  }
  
  public int getScore() { return score; }

  public void setScore(int score) {
    this.score = score;
  }
  
  @Override
  public String toString() {
    return "Student{" + 
            "name='" + name + '\'' +
            ", score=" + score +
            '}';
  }
  
  /*
    this:代表students[i]
    o:代表students[i+1]
    
    如果students[i].getScore()-students[i+1].getScore()>0
      证明数组中的前面一个对象比后面一个对象的分数高
  */
  @Override
  public int compareTo(Object o) {
    Student s = (Student) o;
    return this.getScore() - s.getScore();
  }
}

比较对象就不能comparable。要用comparator。也就是说对比对象要去实现comparator

然后先去掉compareTo这个重写方法。然后去implements Comparator那里放鼠标上去,alt+control出来这个:

然后选择第一个Implement methods

然后就会在这个类中出现这段代码:

java 复制代码
@Override
public int compare(Object o1, Object o2) {
  return 0
}

到时候调这个方法不得对比这两个对象吗?一个是Object o1,一个是Object o2,两个对象都是Object,我们比较的是Student对象,所以把两个参数接收到之后,都向下转型一下,

java 复制代码
@Override
public int compare(Object o1, Object o2) {
  Student s1 = (Student) o1;
  Student s2 = (Student) o2;
  return s1.getScore() - s2.getScore(); // 根据分数分析大小
}

测试类: Test01

java 复制代码
pulic class Test01 {
  public static void main(String[] args) {
    // 创建一个数组
    Student[] students = new Student[3];
    Student s1 = new Student("张三", 100);
    Student s2 = new Student("李四", 60);
    Student s3 = new Student("王五", 80);
    
    students[0] = s1;
    students[1] = s2;
    students[2] = s3;
    
    for (int j = 0; j < students.length - 1; j++) {
      for (int i = 0; i < students.length - 1 - j; i++) {
        // 如果 students[i] 比 students[i+1]大,就排序换位置
        if (students[i].compareTo(students[i+1]) > 0) {
          Student temp = students[i];
          students[i] = students[i+1];
          students[i+1] = temp;
        }
      }
    }
    
    // 遍历
    for (int i = 0; i < students.length; i++) {
      System.out.println(studnets[i]);
    }
  }
}
java 复制代码
pulic class Test01 {
  public static void main(String[] args) {
    // 创建一个数组
    Student[] students = new Student[3];
    Student s1 = new Student("张三", 100);
    Student s2 = new Student("李四", 60);
    Student s3 = new Student("王五", 80);
    
    students[0] = s1;
    students[1] = s2;
    students[2] = s3;
    
    Student student = new Student();
    
    for (int j = 0; j < students.length - 1; j++) {
      for (int i = 0; i < students.length - 1 - j; i++) {
        // 如果 students[i] 比 students[i+1]大,就排序换位置
        if (students.compare(students[i], students[i+1]) > 0) {
          Student temp = students[i];
          students[i] = students[i+1];
          students[i+1] = temp;
        }
      }
    }
    
    // 遍历
    for (int i = 0; i < students.length; i++) {
      System.out.println(studnets[i]);
    }
  }
}

写清楚:

java 复制代码
/*
  o1代表students[i]
  o2代表students[i+1]
  
  如果o1的分数大于o2的分数 -> compare 方法返回正整数
  如果o1的分数小于o2的分数 -> compare 方法返回负整数
  如果o1的分数等于o2的分数 -> compare 犯法返回0
*/
@Override
public int compare(Object o1, Object o2) {
  Student s1 = (Student) o1;
  Student s2 = (Student) o2;
  
  return s1.getScore() - s2.getScore();
}

这就是这个比较器的使用。

相关推荐
IT_陈寒2 小时前
Python 3.12新特性实测:10个让你的代码提速30%的隐藏技巧 🚀
前端·人工智能·后端
BingoGo2 小时前
从零开始打造 Laravel 扩展包:开发、测试到发布完整指南
后端·php
9号达人2 小时前
普通公司对账系统的现实困境与解决方案
java·后端·面试
golang学习记2 小时前
Go 1.26 新特性:netip.Prefix.Compare —— 标准化 IP 子网排序能力
后端
花落已飘2 小时前
openEuler容器化实践:从Docker入门到生产部署
后端
Cache技术分享2 小时前
233. Java 集合 - 遍历 Collection 中的元素
前端·后端
回家路上绕了弯3 小时前
五分钟内重复登录 QQ 号定位:数据结构选型与高效实现方案
分布式·后端
AI三林叔3 小时前
第2章 MCP协议深度解析
后端