活动地址:CSDN21天学习挑战赛
博客主页: XIN-XIANG荣
系列专栏:【Java SE】
一句短话: 难在坚持,贵在坚持,成在坚持!

文章目录

  • 一. Comparable接口
    • 1. Comparable简介
    • 2. 为什么要实现Comparable接口
    • 3. Comparable的实际应用
  • Comparator接口
    • 1. Comparator简介
    • 2. Comparator接口的实际运用
  • 三. Comparable和Comparator的比较

一. Comparable接口

1. Comparable简介

Comparable是排序接口。

若一个类实现了Comparable接口,就意味着该类支持排序。

实现了Comparable接口的类的对象的列表或数组可以通过Collections.sort或Arrays.sort进行自动排序。

Comparable接口的源码

public interface Comparable<T> {public int compareTo(T o);
}

2. 为什么要实现Comparable接口

一个类型实现了Compareable接口,表明了这个类具有了可排序的功能或者说标准,两个对象通过Compareable接口中的compareTo方法的返回值来比较大小。

首先定义一个学生对象, 再给定一个学生对象数组, 对这个对象数组中的元素进行排序(按年龄升序), 我们知道操作数组的工具包Arrays中有一个现成的 sort 方法可以给数组元素进行排序, 能否直接使用这个方法呢?

class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class Test {public static void main(String[] args) {Student[] stu = {new Student("zhansan",18),new Student("lisi", 20),new Student("zhaoliu",15)};Arrays.sort(stu);System.out.println(Arrays.toString(stu));}
}

程序运行时出现了类型转换异常

此时去跳转到异常提示的位置查看,可以发现源码中是将数组元素强制转换为Comparable类型,再去调用其中的compareTo方法,而此时我们自定义类型Student与Comparable毫不相干,Student类中是没有compareTo方法的。

再看一个例子,定义一个字符串数组将其排序后输出

import java.util.Arrays;public class Test {public static void main(String[] args) {String[] str = {"xin","abc","rong","def"};Arrays.sort(str);System.out.println(Arrays.toString(str));}
}

执行发现可以完成排序

再去观察String类的源码,可以发现String类也实现了Comparable接口重写了compareTo方法

此时就可以理解实现Comparable接口的原因

3. Comparable的实际应用

理解了Comparable接口后再来实现 给对象数组排序

让 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法

在 sort 方法中会自动调用 compareTo 方法, compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.

然后比较当前对象和参数对象的大小关系(按年龄来算). 如果当前对象应排在参数对象之前, 返回大于 0 的数字; 如果当前对象应排在参数对象之后, 返回小于于 0 的数字; 如果当前对象和参数对象不分先后, 返回 0; 再次执行程序, 结果就符合预期了.

import java.util.Arrays;class Student implements Comparable<Student>{private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Student o) {if (this.age == o.age){return 0;}else if (this.age < o.age){return -1;}else {return 1;}}
}public class Test {public static void main(String[] args) {Student[] stu = {new Student("zhansan",18),new Student("lisi", 20),new Student("zhaoliu",15)};Arrays.sort(stu);System.out.println(Arrays.toString(stu));}
}

执行结果:

注意事项:

对于 sort 方法来说, 需要传入的数组的每个对象都是 “可比较” 的, 需要具备 compareTo 这样的能力. 通 过重写 compareTo 方法的方式, 就可以定义比较规则.

这里自己实现一个 sort 方法来完成排序过程(使用冒泡排序)

public static void bubbleSort(Comparable[] array) {for (int i = 0; i < array.length-1; i++) {for (int j = 0; j < array.length-1-i; j++) {if(array[j].compareTo(array[j+1]) > 0) {Comparable tmp = array[j];array[j] = array[j+1];array[j+1] = tmp; }}}
}

Comparator接口

1. Comparator简介

Comparator是比较接口,我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口),那么我们就可以建立一个“该类的比较器”来进行排序,这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过实现Comparator来新建一个比较器,然后通过这个比较器对类进行排序。

Comparator接口源码:

public interface Comparator<T> {int compare(T o1, T o2);boolean equals(Object obj);
}

可以看到Comparator接口中包含两个抽象抽象方法,分别是为compare, equals,但类实现此接口时,只需要实现的接口只有compare方法即可;

Java中类都继承于Object类,而Object类默认实现了equals方法,所以类实现Comparator接口,实现类中不需要必须去实现equals方法,可以理解为虽然我们没有去实现,但实现类继承于Object类,相当于实现类中已经默认实现了equals方法

2. Comparator接口的实际运用

Arrays.sort()中有下面给出的重载,可以用来排序自定义类型

  • Arrays.sort(T[] a, Comparator<? super T> c);

此时的sort方法中的第二个参数我们传入一个实现了java.util.Comparator接口的实例,所以在排序自定义类型时可以定义一个比较器去实现

下面分别以以对象的name和age属性定义俩个比较器,分别以这两个比较器去实现排序

在以name进行比较时,实际上是以字符串进行比较,String类实现了Comparable接口,所以可以直接调用comparTo方法。

import java.util.Arrays;
import java.util.Comparator;class AgeComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.getAge() - o2.getAge();}
}class NameComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.getName().compareTo(o2.getName());}
}class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}public String getName() {return name;}public int getAge() {return age;}
}public class Test {public static void main(String[] args) {Student[] stu = {new Student("ghi",18),new Student("def", 15),new Student("abc",20)};System.out.println("以年龄进行排序");Arrays.sort(stu, new AgeComparator());System.out.println(Arrays.toString(stu));System.out.println("再以姓名进行排序");Arrays.sort(stu, new NameComparator());System.out.println(Arrays.toString(stu));}
}

执行结果:

下面的代码是使用比较器比较对象

public class Test {public static void main(String[] args) {Student student1 = new Student("xin",10);Student student2 = new Student("rong",40);AgeComparator ageComparator = new AgeComparator();if(ageComparator.compare(student1,student2) > 0) {System.out.println("student1 > student2");}else if(ageComparator.compare(student1,student2) == 0){System.out.println("student1 = student2");}else{System.out.println("student1 < student2");}}

执行结果:

三. Comparable和Comparator的比较

Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”;而Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。

Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。

Comparable 对类的侵入性非常强, 一但投入使用便不方便再做修改,用起来比较简单,只要实现Comparable 接口的对象直接就成为一个可以比较的对象,需要重写comparTo方法,所以如果想要更换比较方式,就需要对comparTo “大动干戈”。

Comparator 对类的侵入性比较弱, 使用起来非常灵活,用Comparator实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 使用Comparator比较,如果想要更换比较方式,只需要在原来的基础上再增加一个比较器即可。

【Java】Comparable和Comparator接口相关推荐

  1. Java中Comparable和Comparator接口区别分析

    本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧. Comparable 简介 Comp ...

  2. java comparator相等_详解Java中Comparable和Comparator接口的区别

    详解Java中Comparable和Comparator接口的区别 发布于 2020-7-20| 复制链接 摘记: 详解Java中Comparable和Comparator接口的区别本文要来详细分析一 ...

  3. Java学习(90)Java集合排序——Comparator接口介绍、案例:对宠物猫分别按名字升序、年龄降序进行排列

    Java集合排序--Comparator接口介绍.案例:对宠物猫分别按名字升序.年龄降序进行排列 Comparator接口介绍 1. Comparator接口: 2. Comparator接口中的co ...

  4. Java创建comparator对象,Java Comparable 和 Comparator 的详解及区别

    Java Comparable 和 Comparator 的详解及区别 Java 中为我们提供了两种比较机制:Comparable 和 Comparator,他们之间有什么区别呢?今天来了解一下. C ...

  5. Comparable和Comparator接口

    目录 Comparable接口 Comparator接口(比较器) Comparable接口和Comparator的比较 总结 Comparable接口 作用:实现对引用数据类型的比较和排序 使用:待 ...

  6. java compareable接口_Java对象比较-Comparable和Comparator接口使用

    最近在学习贪心算法和动态规划的过程中,里面有一段自然排序的操作,顺便简单了解一下Java中对象比较后排序要使用的两个接口:Comparable和Comparator.如果是数字,直接比较就行,但是如果 ...

  7. Java中Comparable和Comparator接口的区别

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/u010859650/article/details/85009595 Comparable 简介 Comparable 是排序 ...

  8. 使用Comparable、Comparator接口实现对对象数组、List集合自定义排序

    1.实现对象数组排序 (1)方法一,需要排序的对象所属的类实现Comparable接口,复写 comparaTo方法  (2)方法二,需要排序的对象所属的类已经完成无法实现Comparable接口,这 ...

  9. Comparable和Comparator接口是干什么的?列出它们的区别。

    ava提供了只包含一个compareTo()方法的Comparable接口.这个方法可以个给两个对象排序.具体来说,它返回负数,0,正数来表明已经存在的对象小于,等于,大于输入对象. Java提供了包 ...

最新文章

  1. C#给图片添加版权信息
  2. C语言补漏(1)--- char到int赋值的一个陷阱
  3. Sonnedix收购意大利11.2MW光伏电站产品组合
  4. 手把手教你使用spring cloud+dotnet core搭建微服务架构:服务治理(-)
  5. 数博会重磅活动:第二届大数据科学与工程国际会议详细日程
  6. 信息系统工程监理服务及营销策略
  7. 组织来了!特斯拉中国车友俱乐部开启官方认证
  8. Qt图形测绘窗口部件介绍
  9. mac无法充电解决办法!快来get下吧!
  10. eval函数pythonmopn_pytorch:model.train和model.eval用法及区别详解
  11. python编程机械_机器人Python编程与开发
  12. 3.通信原理——随机过程(第七版 樊昌信 曹丽娜编著)
  13. UTF-8转换成GBK
  14. 【周总结】博客第一周小结SSL暑假训练第二周小结
  15. 【私有云平台的搭建——vSphere Client 的安装与配置】
  16. 斜杠青年:人生的多种可能
  17. 网页 flash swf 无法调用 摄像头 问题解决
  18. C#开发自动照片(图片)裁剪(缩放)工具
  19. 20年21年嵌入式校招薪资大曝光!!!
  20. 9.foreign key(外键)

热门文章

  1. 我的世界java刷活塞_我的世界:简单易学的自动刷石机,效率不敢说最高,但速度最快...
  2. Kaiming He论文阅读笔记二——Plain Vision Transformer Backbones for Object Detection
  3. 美国YouTube网站经营模式分析
  4. 机器学习、数据挖掘、深度学习的几个宝藏公众号
  5. 计算机主机的背部接口,iMac背部接口
  6. AM访谈|德科见证参与下的中国3D打印发展沿革
  7. 图形领域GPU标准之战逐鹿并行计算
  8. MP3TAG:ID3V2
  9. 神经网络与深度学习(五)前馈神经网络(2)自动梯度计算和优化问题
  10. 一个AI玩遍多个游戏