给岁月以文明,而不是给文明以岁月。——《三体》

在上一篇文章(传送门)中介绍了JDK为我们提供的常用函数式接口,JDK不仅提供的这些函数式接口,其中一些接口还为我们提供了实用的默认方法,这次我们来介绍一下Comparator复合。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

Comparator的使用

在之前文章的例子中,我们使用Comparator.comparing静态方法构建了一个Comparator接口的实例,我们再来简单介绍一下。先来看一下Mask类是怎么写的:

package one.more.study;

/**
* 口罩
* @author 万猫学社
*/
public class Mask {
public Mask() {
} public Mask(String brand, String type, double price) {
this.brand = brand;
this.type = type;
this.price = price;
} /**
* 品牌
*/
private String brand;
/**
* 类型
*/
private String type;
/**
* 价格
*/
private double price; public String getBrand() {
return brand;
} public void setBrand(String brand) {
this.brand = brand;
} public String getType() {
return type;
} public void setType(String type) {
this.type = type;
} public double getPrice() {
return price;
} public void setPrice(double price) {
this.price = price;
} @Override
public String toString() {
return "Mask{" +
"brand='" + brand + '\'' +
", type='" + type + '\'' +
", price=" + price +
'}';
}
}

然后,根据口罩品牌对口罩列表进行正序排序:

List<Mask> maskList = new ArrayList<>();
maskList.add(new Mask("3M", "KN95",17.8));
maskList.add(new Mask("Honeywell", "KN95",18.8));
maskList.add(new Mask("3M", "FFP2",19.8));
maskList.add(new Mask("Honeywell", "N95",19.5));
maskList.sort(Comparator.comparing(Mask::getBrand));
for (Mask mask : maskList) {
System.out.println(mask);
}

运行结果如下:

Mask{brand='3M', type='KN95', price=17.8}
Mask{brand='3M', type='FFP2', price=19.8}
Mask{brand='Honeywell', type='KN95', price=18.8}
Mask{brand='Honeywell', type='N95', price=19.5}

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

逆序

需求改了,要求按照口罩品牌进行逆序排列,这是还需不需要再构建一个Comparator接口的实例呢?答案是不需要,Comparator接口有一个默认方法reversed可以使其逆序,把上面的例子稍微修改一下:

maskList.sort(Comparator.comparing(Mask::getBrand).reversed());

运行结果如下:

Mask{brand='Honeywell', type='KN95', price=18.8}
Mask{brand='Honeywell', type='N95', price=19.5}
Mask{brand='3M', type='KN95', price=17.8}
Mask{brand='3M', type='FFP2', price=19.8}

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

比较器链

需求又改了,先按照口罩品牌逆序排序,如果口罩品牌一样,再按照口罩类型正序排序。Comparator接口还有一个默认方法thenComparing就是做这个的,它的入参也是一个Function接口的实例,如果前一个比较器的比较结果相同,就当前的比较器再进行比较,我们再来修改一下上面的例子:

maskList.sort(Comparator.comparing(Mask::getBrand)
.reversed()
.thenComparing(Mask::getType));

运行结果如下:

Mask{brand='Honeywell', type='KN95', price=18.8}
Mask{brand='Honeywell', type='N95', price=19.5}
Mask{brand='3M', type='FFP2', price=19.8}
Mask{brand='3M', type='KN95', price=17.8}

需求又又改了,先按照口罩品牌逆序排序,如果口罩品牌一样,再按照口罩价格正序排序。口罩价格是double类型,如果使用thenComparing会导致自动装箱,造成资源的白白浪费。所以,推荐使用thenComparingDouble方法,它的入参是ToDoubleFunction,代码修改如下:

maskList.sort(Comparator.comparing(Mask::getBrand)
.reversed()
.thenComparingDouble(Mask::getPrice));

运行结果如下:

Mask{brand='Honeywell', type='KN95', price=18.8}
Mask{brand='Honeywell', type='N95', price=19.5}
Mask{brand='3M', type='KN95', price=17.8}
Mask{brand='3M', type='FFP2', price=19.8}

类似这样支持基础数据类型的方法还有两个:thenComparingInt方法,它的入参是ToIntFunctionthenComparingLong方法,它的入参是ToLongFunction

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

总结

默认方法名称 作用 入参 入参签名
reversed 逆序
thenComparing 比较器链 Function (T) -> R
thenComparingInt 比较器链 ToIntFunction (T) -> int
thenComparingLong 比较器链 ToLongFunction (T) -> long
thenComparingDouble 比较器链 ToDoubleFunction (T) -> double

《死磕Lambda表达式》系列

微信公众号:万猫学社

微信扫描二维码

获得更多Java技术干货

死磕Lambda表达式(五):Comparator复合的更多相关文章

  1. 死磕Lambda表达式(六):Consumer、Predicate、Function复合

    你的无畏来源于无知.--<三体> 在上一篇文章(传送门)中介绍了Comparator复合,这次我们来介绍一下其他的复合Lambda表达式. Consumer复合 Consumer接口中,有 ...

  2. 死磕Lambda表达式(一):初识Lambda

    弱小和无知不是生存的障碍,傲慢才是.--<三体> 什么是Lambda表达式 Lambda表达式是表示可传递匿名函数的一种简洁方式,Lambda表达式没有名称,但是有参数列表.函数主体.返回 ...

  3. 死磕Lambda表达式(二):Lambda的使用

    城市就是森林,每一个男人都是猎手,每一个女人都是陷阱.--<三体> 在哪使用Lambda表达式? 在上一篇文章(传送门)中介绍了Lambda表达式的基本语法,其中的举了一个Lambda表达 ...

  4. 死磕Lambda表达式(三):更简洁的Lambda

    我们都是阴沟里的虫子,但总还是得有人仰望星空.--<三体> 在之前的文章中介绍了Lambda表达式的基本语法和正确使用姿势,这次我来介绍一些Lambda更简洁的用法. 欢迎关注微信公众号: ...

  5. 死磕Lambda表达式(四):常用的函数式接口

    失去人性,失去很多:失去兽性,失去一切.--<三体> 在Java8支持Lambda表达式以后,为了满足Lambda表达式的一些典型使用场景,JDK为我们提供了大量常用的函数式接口.它们主要 ...

  6. 如何选择普通索引和唯一索引《死磕MySQL系列 五》

    系列文章 一.原来一条select语句在MySQL是这样执行的<死磕MySQL系列 一> 二.一生挚友redo log.binlog<死磕MySQL系列 二> 三.MySQL强 ...

  7. 【死磕JVM】五年 整整五年了 该知道JVM加载机制了!

    类加载 Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程 和那些编译时需要连接工作的语言不 ...

  8. 五分钟,让你明白MySQL是怎么选择索引《死磕MySQL系列 六》

    系列文章 二.一生挚友redo log.binlog<死磕MySQL系列 二> 三.MySQL强人"锁"难<死磕MySQL系列 三> 四.S 锁与 X 锁的 ...

  9. Java8学习(3)- Lambda 表达式

    猪脚:以下内容参考<Java 8 in Action> 本次学习内容: Lambda 基本模式 环绕执行模式 函数式接口,类型推断 方法引用 Lambda 复合 上一篇Java8学习(2) ...

随机推荐

  1. Python Type Hint类型注解

    原文地址:https://realpython.com/python-type-checking/ 在本指南中,你将了解Python类型检查.传统上,Python解释器以灵活但隐式的方式处理类型.Py ...

  2. 拿到webshell之后的事情

    之前搞站都是搞到后台管理员,或者搞到webshell就宣布结束了,,今天终于有机会学习一下后面的操作了. 公司网站为php的站,已经拿到webshell.可以进行菜刀连接. 菜刀虚拟终端 php -m ...

  3. Nuxt 项目性能优化调研

    性能优化,这是面试中经常会聊到的话题.我觉得性能优化应该因具体场景而异,因不同项目而异,不同的手段不同的方案并不一定适合所有项目,当然这其中不乏一些普适的方案,比如耳熟能详的文件压缩,文件缓存,CDN ...

  4. 状压dp 持续更新

    前置知识点:二进制状态压缩,动态规划. 1. AcWing 91 最短Hamilton路径 (https://www.acwing.com/problem/content/93/) 给定一张 n 个点 ...

  5. 查询mysql版本号

    mysql> select version(); +------------+| version() |+------------+| 5.7.23-log |+------------+1 r ...

  6. HTML与CSS 开发常用语义化命名

    一.布局❤️ header 头部/页眉:index 首页/索引:logo 标志:nav/sub_nav 导航/子导航:banner 横幅广告:main/content 主体/内容:container/ ...

  7. webpack从0到1超详细超基础学习教程

    概念 自己是一个一听到webpack就头大,看着一堆不知道那是什么玩意的东西总觉得自己做好前端就行了,但是在使用vue-cli的时候总觉得要改其中的一些东西进行项目初始化的时候能够更好使用!所以想要根 ...

  8. Postgresql存放数组形式的数据

    Postgres 数据库允许把字段定义为可变长度的数组.数据类型既可以是内置类型,也可以是用户自定义的类型或枚举类型. 例如: 创建表 create table demo(name text,subj ...

  9. 一份简明的 Base64 原理解析

    书接上回,在 记一个 Base64 有关的 Bug 一文里,我们说到了 Base64 的编解码器有不同实现,交叉使用它们可能引发的问题等等. 这一回,我们来对 Base64 这一常用编解码技术的原理一 ...

  10. new Date在IE下面兼容问题

    昨天碰到一个bug,用art-template模板进行渲染时候,周视图任务展示失败,都是暂无任务,我以为是模板兼容问题,但最开始我用的时候记得就是IE8的兼容性问题,引入es5-shim.min.js ...