[Java] Comparator接口/compare方法的介绍与使用
上一篇文章讲了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接口分为以下几个步骤:
- 排序时使用sort两个参数的重载方法
- 第二个参数位置通常定义一个Comparator的匿名类
- 与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方法的介绍与使用相关推荐
- Java Comparator接口和compareto方法总结
Comparator接口中compare(Object o1,Object o2)方法是java.util.Comparator接口的方法,它实际上用的是待比较对象的compareTo(Object ...
- JAVA中返回值为字母时_LeetCode#524通过删除字母匹配到字典里最长单词-java中CompareTo方法用法以及Comparator中Compare方法返回值...
import java.util.Collections; import java.util.Comparator; import java.util.List; /* 524. 通过删除字母匹配到字 ...
- Java 程序连接 Informix 数据库方法实例介绍
Java 程序连接 Informix 数据库方法实例介绍 Informix 是一种应用广泛的关系型数据库服务器,支持多种类型的客户端连接程序,包括 .Net.Java.PHP 等.对于 Java 程序 ...
- Comparator中compare方法的使用
Comparator中compare方法的使用 首先要明确Comparator是一个函数式接口(有@FunctionalInterface注解),说明可以使用Lambda表达式完成比较操作,并且其中T ...
- java定义接口的方法_java定义接口的方法
java定义接口的方法 发布时间:2020-06-28 13:50:49 来源:亿速云 阅读:103 作者:Leah 本篇文章为大家展示了java定义接口的方法,代码简明扼要并且容易理解,绝对能使你眼 ...
- Java Comparator接口
Java Comparator接口 代码演示 演示1. package Practice;import java.util.ArrayList;import java.util.Collections ...
- Java 9 接口私有方法
Java 9 接口私有方法 Java 9已经发布,并且已经发生了很多变化.今天我们将研究接口中Java 9私有方法的变化. 目录[ 隐藏 ] 1接口中的Java 9私有方法 1.1 Java 7接口 ...
- java comparator接口类_常见的接口与类 -- Comparator
接口Comparator 1.1 前面我们讲过Java提供了一个用于比较的接口Comparable,提供了一个比较的方法,所有实现该接口的类,都动态的实现了该比较方法.实际上Java中除了比较一个接口 ...
- Comparator的compare方法如何定义升序降序
最近做算法题用了Comparator接口下的compare方法,思考了一下升序和降序的规则是如何来的,现在做一个补充,方便以后回顾. 升序代码 public static void main(Str ...
最新文章
- 活动目录系列之一:主域控制器的搭建
- ofstream与ate的故事 经典!
- 比尔-盖茨写给即将走出学校、踏入社会的青年一代的11点忠告
- UVA 10404 - Bachet's Game
- java settime_Java日历setTime()方法及示例
- 成为oa的飞鸽传书重要标准应用与开发平台
- leetcode - 1105. 填充书架
- POJ2931不平等博弈
- Oracle外键级联删除和级联更新
- 利用ObjectMapper进行对象与JSON互相转化
- Nacos初探(2)-- 服务注册原理解析
- NOR Flash与NAND Flash区别
- [深度学习论文笔记]UCTransNet:从transformer的通道角度重新思考U-Net中的跳跃连接
- IOI2015部分题解
- 全力以赴助梦起航 | 盐城北大青鸟祝各位中考考生万事胜意前程似锦
- 乐优商城之后台管理系统的环境搭建(七)
- chrome版本更新后,chromedriver对应版本更新
- 透过数据读懂纷繁世界 中译语通“NexMagic再·奇迹”年度峰会召开
- Spark word2vec使用
- 英语单词记忆以及句式记忆