Comparable 和 Comparator的理解

简介: Comparable是一个排序接口 此接口给实现类提供了一个排序的方法,此接口有且只有一个方法

对Comparable 的解释

Comparable是一个排序接口

此接口给实现类提供了一个排序的方法,此接口有且只有一个方法

public int compareTo(T o);

compareTo方法接受任意类型的参数,来进行比较

list或者数组实现了这个接口能够自动的进行排序,相关类的方法有Collections.sort(),Arrays.sort();

SortedMap 接口的key内置了compareTo方法来进行键排序,SortedSet 也是内置了compareTo方法作为其内部元素的比较手段

compareTo()方法与equals()方法的比较

compareTo()方法不同于equals()方法,它的返回值是一个int类型

int a = 10 , b = 20 , c = 30 , d = 30;
a.compareTo(b) // 返回 -1 说明 a 要比 b 小
c.compareTo(b) // 返回 1 说明 c 要比 b 大
d.compareTo(c) // 返回 0 说明 d 和c 相等

而equals 方法返回的是boolean 类型

x.equals(y) // true 说明x 与 y 的值 相等 , false 说明x 与 y 的值 不相等

代码

Comparable 更像是一个内部排序接口,一个类实现了Comparable比较器,就意味着它本身支持排序;可以用Collections.sort() 或者 Arrays.sort() 进行排序

public class Student implements Comparable<Student>{
   String name;
   int record;
   public Student(){}
   public Student(String name,int record){
       this.name=name;
       this.record=record;
  }
   public boolean equals(Student student) {
       // 拿名字和成绩进行对比
       return name.equals(student.name)
               &&record == student.record;
  }
   @Override
   public int compareTo(Studentstu) {
       // 调用String 类的compareTo方法,返回值 -1,0,1
       return this.name.compareTo(stu.name);
  }
   get and set...
}
public class ComparableTest{
   public static void main(String[] args) {
       List<Student> studentList = Arrays.asList(new Student("liming", 90),
               new Student("xiaohong", 95),
               new Student("zhoubin", 88),
               new Student("xiaoli", 94)
      );
// 排序前
       System.out.println(studentList);
       Collections.sort(studentList);
       // 排序后
       System.out.println(studentList);
       for(Student student : studentList){
           System.out.println(student.equals(new Student("xiaohong", 95)));
      }
  }
}

输出:

[liming = 90, xiaohong = 95, zhoubin = 88, xiaoli = 94][liming = 90, xiaohong = 95, xiaoli = 94, zhoubin = 88]

false true false false

compareTo()方法抛出异常

public int compareTo(To);

NullPointerException : 如果 对象o为null,抛出空指针异常

ClassCastException: 如果需要类型转换之后进行比较,可能会抛出ClassCastException


对Comparator 的解释

Comparator 相当于一个比较器,作用和Comparable类似,也是使用Collections.sort() 和 Arrays.sort()来进行排序,也可以对SortedMap 和 SortedSet 的数据结构进行精准的控制,你可以不用实现此接口或者Comparable接口就可以实现次序比较。 TreeSet 和 TreeMap的数据结构底层也是使用Comparator 来实现。不同于Comparable ,比较器可以任选地允许比较null参数,同时保持要求等价关系。

Comparator比较器的方法

int compare(T o1, T o2);

compare() 方法的用法和Comparable 的 compareTo() 用法基本一样,这个方法不允许进行null值比较,会抛出空指针异常

boolean equals(Object obj);

jdk1.8 之后又增加了很多新的方法

33.jpg

很多都是关于函数式编程的,在这里先不做讨论了

代码实现

public class AscComparator implements Comparator<Student>{
   @Override
   public int compare(Student stu1, Student stu2) {
       // 根据成绩降序排列
       return stu1.getRecord() - stu2.getRecord();
  }
}
public class ComparatorTest{
   public static void main(String[] args) {
       List<Student> studentList = Arrays.asList(new Student("liming", 90),
               new Student("xiaohong", 95),
               new Student("zhoubin", 88),
               new Student("xiaoli", 94)
      );
       // 1. 可以实现自己的外部接口进行排序
       Collections.sort(studentList,new AscComparator());
       System.out.println(studentList);
       // 2、 可以匿名内部类实现自定义排序
       Collections.sort(studentList, new Comparator<Student>() {
           @Override
           public int compare(Student stu1, Student stu2) {
               return stu2.getRecord() -stu1.getRecord();
          }
      });
       System.out.println(studentList);
  }
}

也可以使用Arrays.sort()进行排序,不过针对的数据结构是数组。


Comparable 和 Comparator 的对比

1、Comparable 更像是自然排序

2、Comparator 更像是定制排序

同时存在时采用 Comparator(定制排序)的规则进行比较。

对于一些普通的数据类型(比如 String, Integer, Double…),它们默认实现了Comparable 接口,实现了 compareTo 方法,我们可以直接使用。

而对于一些自定义类,它们可能在不同情况下需要实现不同的比较策略,我们可以新创建 Comparator 接口,然后使用特定的 Comparator 实现进行比较。

相关文章
|
Java 应用服务中间件 API
Flowable UI Web应用搭建教程(图解)
Flowable UI Web应用搭建教程(图解)
1094 0
一个免费功能强大的谷歌翻译api
分享一个免费且功能强大谷歌翻译api
11008 2
一个免费功能强大的谷歌翻译api
|
存储 Java 开发者
Java 里的“变形金刚”:变量与常量的前世今生!
【6月更文挑战第14天】Java 中的变量和常量是编程基础,变量是可变的容器,用于存储不同类型的数据,如示例中的 `age`;常量(如 `MAX_VALUE`)是固定不变的值,用 `final` 定义。理解两者及其作用至关重要,它们确保程序的稳定性和准确性。在实际编程中,合理使用变量和常量可以提高代码可读性和可维护性。它们是构建程序的基础,对新手和资深开发者都极其重要。
107 4
|
存储 Java
【数据结构】队列的使用|模拟实现|循环队列|双端队列|面试题
【数据结构】队列的使用|模拟实现|循环队列|双端队列|面试题
216 1
|
Android开发 iOS开发
了解iOS消息推送一文就够:史上最全iOS Push技术详解
本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表。 1、引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ、微信等IM界面处于前台时,聊天消息和指令都会通过IM自建的网络长连接通道推送过来,这种Pu...
3739 0
|
XML 前端开发 Java
【Spring】——Spring生命周期
【Spring】——Spring生命周期
144 0
【Spring】——Spring生命周期
|
Kubernetes Cloud Native JavaScript
【Quarkus技术系列】「云原生架构体系」配置参考指南相关的功能机制配置介绍分析
【Quarkus技术系列】「云原生架构体系」配置参考指南相关的功能机制配置介绍分析
637 0
【Quarkus技术系列】「云原生架构体系」配置参考指南相关的功能机制配置介绍分析
|
Java Windows
Java-CentoOS 7安装JDK8 (rpm格式 和 tar.gz格式)& 多JDK设置默认的Java 版本
Java-CentoOS 7安装JDK8 (rpm格式 和 tar.gz格式)& 多JDK设置默认的Java 版本
441 0
|
自然语言处理 JavaScript 物联网
物联网操作系统概述
物联网操作系统概述
578 4
物联网操作系统概述
|
关系型数据库 MySQL 数据库
Sqlmap学习 -- Tapmer绕过脚本(三)
Sqlmap学习 -- Tapmer绕过脚本(三)
354 0