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

在上一篇文章(传送门)中介绍了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. 算发帖&mdash;&mdash;俄罗斯方块覆盖问题一共有多少个解

    问题的提出:如下图,用13块俄罗斯方块覆盖8*8的正方形.   那么一共可以有多少个解呢?(若通过旋转.翻转一个解而得到的新解,则两个解视为同一个解)   首先,求解的问题,已经在上一篇帖子里完成 算 ...

  2. 如何正确使用redis分布式锁

    前言   笔者在公司担任技术面试官,在笔者面试过程中,如果面试候选人提到了reids分布式锁,笔者都会问一下redis分布式锁的知识点,但是令笔者遗憾的是,该知识点十个人中有九个人都答得不清楚,或者回 ...

  3. Java入门教程十一(异常处理)

    在程序设计和运行的过程中,发生错误是不可避免的.尽管 Java 语言的设计从根本上提供了便于写出整洁.安全代码的方法,并且程序员也尽量地减少错误的产生,但是使程序被迫停止的错误的存在仍然不可避免.为此 ...

  4. python webp转jpg

    webp格式转jpg格式 从网页上保存下来的webp格式的图片用ps和一些看图软件打不开,所以需要进行下转换. 直接上py代码.代码用到了PIL库,如果电脑上没有还需要pip install Pill ...

  5. 三个值得期待的JavaScript新功能!

    让我们来看看JavaScript中一些有用的即将推出的功能.您将看到他们的语法,链接以及时了解他们的进度,我们将编写一个小型测试套件,以展示如何立即开始使用这些提案! JavaScript是如何更新迭 ...

  6. Simple: 一个支持中文和拼音搜索的 sqlite fts5插件

    之前的工作关系,需要在手机上支持中文和拼音搜索.由于手机上存储数据一般都是用 sqlite,所以是基于 sqlite3 fts5 来实现.这段时间再次入门 c++,所以想用 c++ 实现一下,一来用于 ...

  7. Spring Cloud Gateway 实现Token校验

    在我看来,在某些场景下,网关就像是一个公共方法,把项目中的都要用到的一些功能提出来,抽象成一个服务.比如,我们可以在业务网关上做日志收集.Token校验等等,当然这么理解很狭隘,因为网关的能力远不止如 ...

  8. 使用ZXingObjC扫描二维码横竖屏对应

    /** 根据屏幕的方向设置扫描的方向 * @author maguang * @param parameter * @return result */ - (void)showaCapture { C ...

  9. 2019-2020-2 20174318张致豪《网络对抗技术》Exp1 PC平台逆向破解

    Exp1_PC平台逆向破解 前期准备 一.逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数 ...

  10. http2 技术整理 nginx 搭建 http2 wireshark 抓包分析 server push 服务端推送

    使用 nginx 搭建一个 http2 的站点,准备所需: 1,域名 .com .net 均可(国内域名需要 icp 备案) 2,云主机一个,可以自由的安装配置软件的服务器 3,https 证书 ht ...