上一篇文章讲了Comparable接口的使用,建议搭配食用。

背景

在实现Comparable接口的前提下,对象间已经有一套可适用的大小比较规则/排序规则了。然而某些情况下,由compareTo定义的排序规则不再适用,需要一套新的规则,我们该怎么做呢?

修改源码中的compareTo方法或许是可行的,然而这样的弊端也颇多:

  • 不方便,每次更换排序规则都需要找到定义处去修改。
  • 若同一个代码块中同时要运用两种排序规则,修改源码只能适用于其中一种。
  • String类和包装类默认重写了compareTo方法,若需要更改他们的比较规则,修改源码需要直接修改JDK本身。

可见,改源码不见得是一个好的选择。而JDK为了解决这个问题提供了更具普适性的方案:Comparator接口。

介绍

这个长得非常像Comparable的和它一样,也是个带泛型的接口。
compare方法和compareTo方法长得也很像,两者主要区别是前者含两个形参,后者仅有一个。
两者主要在应用方式上有较大的区别,下面将通过举例来详细叙述这一部分。

使用举例

我们知道字符串String默认的排序顺序是由小到大进行排序,那当我们需要其由大到小进行排序,应该怎么做?

 @Testpublic void test3(){String[] arr = new String[]{"AA","BB","ZZ","DD","CC"};Arrays.sort(arr, new Comparator<String>() {// 按照字符串从大到小的顺序排列@Overridepublic int compare(String o1, String o2) {return -o1.compareTo(o2);}});// 这是个匿名类System.out.println(Arrays.toString(arr));// [ZZ, DD, CC, BB, AA]}

仔细观察上端代码,不难发现其与对String直接排序的区别在于Array.sort方法新增了一个参数,该位置要求传入一个Comparator接口的实现对象。这里通常为简洁起见会直接使用一个匿名类充当。

定义匿名类后重点在于需要重写其compare方法,重写规则与compareTo方法相同,仅仅是形参变成两个。在数组排序中,o1是指前一个元素,o2是指后一个元素。

重写规则:o1大于o2时,返回正整数;反之返回负整数,相等返回0。与compareTo的重写规则相同。

总结来说,使用Comparator接口分为以下几个步骤:

  1. 排序时使用sort两个参数的重载方法
  2. 第二个参数位置通常定义一个Comparator的匿名类
  3. 与compareTo相同的规则去重写匿名类的compare方法,使其按照需要的比较关系返回相应的数值

自定义类举例

清楚基本的使用方法后,我们再看看其在自定义类中的使用。
首先我们自定义了这么个类:

public class Product implements Comparable {private String name;private double price;public Product(String name, double price) {this.name = name;this.price = price;}...

该类重写了compareTo方法,按产品价格从低到高进行排序。具体如下:

    @Overridepublic int compareTo(Product o) {if (this.price > product.price)return 1;else if (this.price < product.price)return -1;else return 0;}   // 这种写法是按价格从低到高进行排序

重写了compareTo方法后通过sort我们可以直接对Product的数组按价格升序进行排序。而倘若这时候我们需要按名称进行排序,同时若名称相同则按价格进行二级排序呢?

    @Testpublic void test4(){Product[] arr = new Product[4];arr[0] = new Product("A",59);arr[1] = new Product("B",12);arr[2] = new Product("C",44);arr[3] = new Product("D",102);Arrays.sort(arr, new Comparator<Product>() {@Overridepublic int compare(Product o1, Product o2) {if (o1.getName().equals(o2.getName())){return -Double.compare(o1.getPrice(),o2.getPrice());}else {return o1.getName().compareTo(o2.getName());}}});   // 未实现Comparable接口会抛异常System.out.println(Arrays.toString(arr));}

其实与上文提到的String类操作大同小异,无非是重写函数的内部稍微复杂了些。

总结

基于上述内容,我们可以来个小的总结。

  • 实现Comparable接口重写compareTo方法指定的排序规则更为适用,应当用于能应付较多的一般性情景的排序规则,因此又被成为“自然排序”。
  • 通过Comparator接口进行比较的情况下更适用于已经实现了Comparable接口,但需要临时调整一次新的排序规则的情形下,因此又被称为“定制排序”

[Java] Comparator接口/compare方法的介绍与使用相关推荐

  1. Java Comparator接口和compareto方法总结

    Comparator接口中compare(Object o1,Object o2)方法是java.util.Comparator接口的方法,它实际上用的是待比较对象的compareTo(Object ...

  2. JAVA中返回值为字母时_LeetCode#524通过删除字母匹配到字典里最长单词-java中CompareTo方法用法以及Comparator中Compare方法返回值...

    import java.util.Collections; import java.util.Comparator; import java.util.List; /* 524. 通过删除字母匹配到字 ...

  3. Java 程序连接 Informix 数据库方法实例介绍

    Java 程序连接 Informix 数据库方法实例介绍 Informix 是一种应用广泛的关系型数据库服务器,支持多种类型的客户端连接程序,包括 .Net.Java.PHP 等.对于 Java 程序 ...

  4. Comparator中compare方法的使用

    Comparator中compare方法的使用 首先要明确Comparator是一个函数式接口(有@FunctionalInterface注解),说明可以使用Lambda表达式完成比较操作,并且其中T ...

  5. java定义接口的方法_java定义接口的方法

    java定义接口的方法 发布时间:2020-06-28 13:50:49 来源:亿速云 阅读:103 作者:Leah 本篇文章为大家展示了java定义接口的方法,代码简明扼要并且容易理解,绝对能使你眼 ...

  6. Java Comparator接口

    Java Comparator接口 代码演示 演示1. package Practice;import java.util.ArrayList;import java.util.Collections ...

  7. Java 9 接口私有方法

    Java 9 接口私有方法 Java 9已经发布,并且已经发生了很多变化.今天我们将研究接口中Java 9私有方法的变化. 目录[ 隐藏 ] 1接口中的Java 9私有方法 1.1 Java 7接口 ...

  8. java comparator接口类_常见的接口与类 -- Comparator

    接口Comparator 1.1 前面我们讲过Java提供了一个用于比较的接口Comparable,提供了一个比较的方法,所有实现该接口的类,都动态的实现了该比较方法.实际上Java中除了比较一个接口 ...

  9. Comparator的compare方法如何定义升序降序

    最近做算法题用了Comparator接口下的compare方法,思考了一下升序和降序的规则是如何来的,现在做一个补充,方便以后回顾.  升序代码 public static void main(Str ...

最新文章

  1. 活动目录系列之一:主域控制器的搭建
  2. ofstream与ate的故事 经典!
  3. 比尔-盖茨写给即将走出学校、踏入社会的青年一代的11点忠告
  4. UVA 10404 - Bachet's Game
  5. java settime_Java日历setTime()方法及示例
  6. 成为oa的飞鸽传书重要标准应用与开发平台
  7. leetcode - 1105. 填充书架
  8. POJ2931不平等博弈
  9. Oracle外键级联删除和级联更新
  10. 利用ObjectMapper进行对象与JSON互相转化
  11. Nacos初探(2)-- 服务注册原理解析
  12. NOR Flash与NAND Flash区别
  13. [深度学习论文笔记]UCTransNet:从transformer的通道角度重新思考U-Net中的跳跃连接
  14. IOI2015部分题解
  15. 全力以赴助梦起航 | 盐城北大青鸟祝各位中考考生万事胜意前程似锦
  16. 乐优商城之后台管理系统的环境搭建(七)
  17. chrome版本更新后,chromedriver对应版本更新
  18. 透过数据读懂纷繁世界 中译语通“NexMagic再·奇迹”年度峰会召开
  19. Spark word2vec使用
  20. 英语单词记忆以及句式记忆

热门文章

  1. Java多数据源最通俗讲解
  2. 软件开发、设计、架构的五大原则
  3. 有了这个sku分析!老板再也不用担心我不会选款备货了
  4. Android小窗口模式,picture-in-picture(PIP画中画)的使用
  5. OpenHarmony介绍及相关资料
  6. js删除数组中的指定对象
  7. MBA-day1数学-应用题-利润问题
  8. Mysql数据库使用规范
  9. Sentinel 极简入门
  10. proteus中仿真51单片系列之---blink点灯程序