Java 可用于比较与排序的lambda表达式和comparing方法

  • 温故而知新
  • lambda表达式
    • (parameters) -> { statements; }方式进行比较
    • (parameters) -> expression方式进行比较
    • lambda表达式用于输出
  • 使用comparing()方法进行排序

在上一篇博客中,我介绍了Comparable与Comparator的简单用法,同时也挖坑说要介绍JDK1.8新引入的lambda表达式用来比较,和comparing方法用来比较。这几天学习了一下,将学习笔记记录在本博客中。

温故而知新

首先复原我们上一篇博客中Java 自定义比较与排序方法Comparable与Comparator的简单使用用到的类,和用Compartor接口进行比较:
用到的类:

public class Student {String name; // 学生的姓名int id; // 学生的学号double score; // 学生的成绩Paper p; // 学生发表的论文Student(String name, int id, double score) {this.name = name;this.id = id;this.score = score;}Student(String name, int id, double score, Paper p) {this.name = name;this.id = id;this.score = score;this.p = p;}
}class Paper {char rank; // 论文发表期刊或会议的水平,分'A','B','C'级,'A'类最好,'B'类次之,'C'类最差double impact_factor; // 论文发表期刊或会议的影响因子Paper(char rank, double impact_factor) {this.rank = rank;this.impact_factor = impact_factor;}
}

使用Compartor进行比较:

import java.util.*;public class Try {public static void main(String[] args) {Paper p1 = new Paper('A', 2.91);Paper p2 = new Paper('B', 1.67);Paper p3 = new Paper('A', 3.89);Student s1 = new Student("Zhang San", 1, 80, p1);Student s2 = new Student("Li Si", 2, 90, p2);Student s3 = new Student("Wang Wu", 3, 70, p3);List<Student> l = new LinkedList<>();l.add(s1);l.add(s2);l.add(s3);l.sort(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {if (o1.p.rank > o2.p.rank) { // rank越大,论文越差,所以这里是当rank较大时,返回-1,表示论文发得差return -1;} else if (o1.p.rank < o2.p.rank) {return 1;} else {return Double.compare(o1.p.impact_factor, o2.p.impact_factor);}}});System.out.printf("论文发得最好的人的姓名为%s,学号为%d\n", l.get(2).name, l.get(2).id);System.out.printf("论文发得第二好的人的姓名为%s,学号为%d\n", l.get(1).name, l.get(1).id);System.out.printf("论文发得最差的人的姓名为%s,学号为%d\n", l.get(0).name, l.get(0).id);}
}

lambda表达式

lambda表达式是JDK1.8中新添加的一个非常强大功能,它可以用来做比较,也可以实现更厉害的一些功能,一会我们在输出时也可以看到它的强力发挥。
首先介绍一下lambda表达式的语法:
(parameters) -> expression

(parameters) -> { statements; }
其中,expression是一个表达式,是可以求出值的式子,可以用到在parameters中提到的变量。
{statements;}是一块代码段,在这里实现我们需要的一些功能。要注意的是,如果在statements中用到了外部变量,那么该外部变量必须是由final关键字修饰的。其原理和匿名内部类中使用外部变量必须是由final关键字修饰的类似。

(parameters) -> { statements; }方式进行比较

lambda表达式大大简化了代码,下面我们看一下lambda表达式怎么替代Compartor来进行比较。完整版代码如下,注意观察l.sort()方法的变化:

import java.util.*;public class Try {public static void main(String[] args) {Paper p1 = new Paper('A', 2.91);Paper p2 = new Paper('B', 1.67);Paper p3 = new Paper('A', 3.89);Student s1 = new Student("Zhang San", 1, 80, p1);Student s2 = new Student("Li Si", 2, 90, p2);Student s3 = new Student("Wang Wu", 3, 70, p3);List<Student> l = new LinkedList<>();l.add(s1);l.add(s2);l.add(s3);l.sort((Student o1, Student o2) -> {if (o1.p.rank > o2.p.rank) { // rank越大,论文越差,所以这里是当rank较大时,返回-1,表示论文发得差return -1;} else if (o1.p.rank < o2.p.rank) {return 1;} else {return Double.compare(o1.p.impact_factor, o2.p.impact_factor);}});System.out.printf("论文发得最好的人的姓名为%s,学号为%d\n", l.get(2).name, l.get(2).id);System.out.printf("论文发得第二好的人的姓名为%s,学号为%d\n", l.get(1).name, l.get(1).id);System.out.printf("论文发得最差的人的姓名为%s,学号为%d\n", l.get(0).name, l.get(0).id);}
}

输出后可以得到相同的结果:

论文发得最好的人的姓名为Wang Wu,学号为3
论文发得第二好的人的姓名为Zhang San,学号为1
论文发得最差的人的姓名为Li Si,学号为2

在这里我们使用到了(parameters) -> { statements; }这种方式,parameters中我们设置了两个Student对象,在statement中进行了比较方法的实现。

(parameters) -> expression方式进行比较

我们再使用一下(parameters) -> expression这种方式,进行一个简单的比较,比如比较成绩:

import java.util.*;public class Try {public static void main(String[] args) {Paper p1 = new Paper('A', 2.91);Paper p2 = new Paper('B', 1.67);Paper p3 = new Paper('A', 3.89);Student s1 = new Student("Zhang San", 1, 80, p1);Student s2 = new Student("Li Si", 2, 90, p2);Student s3 = new Student("Wang Wu", 3, 70, p3);List<Student> l = new LinkedList<>();l.add(s1);l.add(s2);l.add(s3);l.sort((Student o1, Student o2) -> Double.compare(o1.score, o2.score));System.out.printf("成绩最好的人的姓名为%s,学号为%d\n", l.get(2).name, l.get(2).id);System.out.printf("成绩第二好的人的姓名为%s,学号为%d\n", l.get(1).name, l.get(1).id);System.out.printf("成绩最差的人的姓名为%s,学号为%d\n", l.get(0).name, l.get(0).id);}
}

输出结果为:

成绩最好的人的姓名为Li Si,学号为2
成绩第二好的人的姓名为Zhang San,学号为1
成绩最差的人的姓名为Wang Wu,学号为3

这就是lambda表达式用于排序的威力,非常简短明了。

lambda表达式用于输出

lambda还有其他很多功能,在这里尝试一下用它改善我们的输出。
我们知道,如果要将一个班级中所有人的成绩都输出,需要使用到循环,其中我们可以使用语法糖for ( : )的结构来简化循环。而对于一个List,lambda方法可以更加简便地使用foreach,比如按照成绩大小从高到低排序输出,示例代码如下:

import java.util.*;public class Try {public static void main(String[] args) {Paper p1 = new Paper('A', 2.91);Paper p2 = new Paper('B', 1.67);Paper p3 = new Paper('A', 3.89);Student s1 = new Student("Zhang San", 1, 80, p1);Student s2 = new Student("Li Si", 2, 90, p2);Student s3 = new Student("Wang Wu", 3, 70, p3);List<Student> l = new LinkedList<>();l.add(s1);l.add(s2);l.add(s3);l.sort((Student o1, Student o2) -> Double.compare(o2.score, o1.score)); // 改为按成绩非递增排序System.out.println("将成绩由高到低排序:");l.forEach((ele) -> System.out.printf("姓名为%s,学号为%d,成绩为%.2f\n", ele.name, ele.id, ele.score));}
}

输出结果为:

将成绩由高到低排序:
姓名为Li Si,学号为2,成绩为90.00
姓名为Zhang San,学号为1,成绩为80.00
姓名为Wang Wu,学号为3,成绩为70.00

可以看到输出时我们用到了lambda表达式,不用写for循环,更方便地进行输出。

使用comparing()方法进行排序

在Compartor接口中有一个方法comparing()也可以进行排序,这也是JDK1.8的新特性。该方法与lambda表达式密切相关。不过我现在查到的资料都是说它只能完成简单规则的比较,而无法实现我们在比较发表论文好坏时,先比较rank,如果相同再比较impact_factor的复杂规则。(如果有大神了解这块内容的话,请多多赐教啊!)
简单地用该方法来实现成绩由高到低的排序:

import java.util.*;public class Try {public static void main(String[] args) {Paper p1 = new Paper('A', 2.91);Paper p2 = new Paper('B', 1.67);Paper p3 = new Paper('A', 3.89);Student s1 = new Student("Zhang San", 1, 80, p1);Student s2 = new Student("Li Si", 2, 90, p2);Student s3 = new Student("Wang Wu", 3, 70, p3);List<Student> l = new LinkedList<>();l.add(s1);l.add(s2);l.add(s3);l.sort(Comparator.comparing(o -> -o.score)); // 由于默认的是从低到高,我们加个负号,就能实现从高到低System.out.println("将成绩由高到低排序:");l.forEach((ele) -> System.out.printf("姓名为%s,学号为%d,成绩为%.2f\n", ele.name, ele.id, ele.score));}
}

输出结果为:

将成绩由高到低排序:
姓名为Li Si,学号为2,成绩为90.00
姓名为Zhang San,学号为1,成绩为80.00
姓名为Wang Wu,学号为3,成绩为70.00

个人觉得这两个JDK1.8的新特性挺好的,尤其是lambda表达式,它让Java有了函数式编程的风格(有Python内味了~)。lambda表达式还有更多内容和有趣的用例,都值得去深入学习。

Java 可用于比较与排序的lambda表达式和comparing方法相关推荐

  1. 【Java】 第六章 接口、lambda 表达式与内部类 Java核心技术卷1基础知识原书第10版 读书笔记

    第六章 接口.lambda表达式与内部类 6. 接口.lambda 表达式与内部类 6.1 接口 6.1.1 接口概念 6.1.2 接口的特性 6.1.3 接口与抽象类 6.1.4 静态方法 6.1. ...

  2. JAVA学习笔记 15 - 函数式接口、Lambda表达式和方法引用

    本文是Java基础课程的第十五课.主要介绍在JDK8中,Java引入的部分新特性,包括函数式接口.Lambda表达式和方法引用.这些新特性使得Java能够在按照面向对象思想进行开发的基础上,融合函数式 ...

  3. java convert函数_Java 函数式编程和Lambda表达式

    1.Java 8最重要的新特性 Lambda表达式.接口改进(默认方法)和批数据处理. 2.函数式编程 本质上来说,编程关注两个维度:数据和数据上的操作. 面向对象的编程泛型强调让操作围绕数据,这样可 ...

  4. intellij-IDE运行Java程序报错:java: -source 1.5 中不支持 lambda 表达式 有用

    intellij-IDE运行Java程序报错:java: -source 1.5 中不支持 lambda 表达式 2017年12月29日 15:04:15 佛空如水 阅读数:795 报错: 解决: 第 ...

  5. java list作为参数传递_Java 程序将lambda表达式作为方法参数传递

    Java 程序将lambda表达式作为方法参数传递 在此示例中,我们将学习将lambda表达式作为Java中的方法参数传递. 要理解此示例,您应该了解以下Java编程主题: 示例1:将lambda表达 ...

  6. Java从入门到精通十四(Lambda表达式)

    Java从入门到精通十四(Lambda表达式) Lambda的引入体验 实例一(抽象方法无参无返回值) 实例二(抽线方法有参无返回值) 实例三(抽象方法带参带返回值) lambda的表达式的简化操作 ...

  7. Java 8:将匿名类转换为Lambda表达式

    将匿名类(实现一种方法)重构为lambda表达式,可使您的代码更简洁明了. 例如,这是Runnable及其lambda等效项的匿名类: // using an anonymous class Runn ...

  8. Lambda表达式接口更新方法引用函数式接口Stream流

    Lambda表达式&接口更新&方法引用&函数式接口&Stream流 Lambda 1.程序启动三种不同的表现形式 2.Lambda表达式的标准格式 3.练习 Lambd ...

  9. C# lambda表达式与匿名方法

    文章目录 匿名方法 Lambda表达式 实例 实例 博主写作不容易,孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 C#中的匿名方法是在C#2.0引入的,它终结了声明委托的唯一方法是使用命名方法的 ...

  10. lambda表达式方法泛型_模板方法模式–使用Lambda表达式,默认方法

    lambda表达式方法泛型 模板方法模式是Erich Gamma,Richard Helm,Ralph Johnson和John Vlissides在著名的< 设计模式>一书中解释的23种 ...

最新文章

  1. “远征记”——从燕郊骑自行车回京
  2. Django系列之启动入口源码分析
  3. 怎么用BarTender批量打印标签
  4. 跟JBPM学设计模式之适配器模式
  5. QTP对象TO与RO
  6. Java加密与解密的艺术~数字证书~证书管理openssl
  7. vue tree组件_使用Vue 3.0做JSX(TSX)风格的组件开发
  8. UEditor 1.36 版本 jsp版上传图片自定义路劲配置
  9. 跨域异常与nginx的underscores_in_headers on
  10. Software--Architecture--SOA Factory
  11. os.path.join;os.makedirs()
  12. tomcat运行的本质
  13. 《植物大战僵尸》游戏数据修改
  14. 【AD封装】2.4G PCB天线(量产用)
  15. Elasticsearch:运用 Elasticsearch 查找类似文档:more_like_this
  16. 导出虚拟机的OVF 模板
  17. 苹果怎么把某个app隐藏_怎么给苹果手机APP加密?
  18. 做UI设计需要具备什么技能
  19. HTTP错误代码 404 503 500
  20. 前端项目中package.json到底是什么,又充当着什么作用呢?一文来带你了解package.json!

热门文章

  1. 重新开始学Java——java中的标识符(biao,zhi,fu)、关键字和代码规范
  2. Linux命令英文全称
  3. 故障恢复控制台应用指南
  4. bootloader相关
  5. Linux驱动regulator
  6. 数字图像处理-高反差保留算法
  7. Linux软件包管理工具-yum
  8. “蔚来杯“2022牛客暑期多校训练营5 Don‘t Starve
  9. 【Java小游戏】两小时制作大鱼吃小鱼小游戏项目
  10. qt实现视频播放器,基本功能都有,可以当毕设用