概述
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>() {
@Override
public 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,学号为%dn", l.get(2).name, l.get(2).id);
System.out.printf("论文发得第二好的人的姓名为%s,学号为%dn", l.get(1).name, l.get(1).id);
System.out.printf("论文发得最差的人的姓名为%s,学号为%dn", 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,学号为%dn", l.get(2).name, l.get(2).id);
System.out.printf("论文发得第二好的人的姓名为%s,学号为%dn", l.get(1).name, l.get(1).id);
System.out.printf("论文发得最差的人的姓名为%s,学号为%dn", 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,学号为%dn", l.get(2).name, l.get(2).id);
System.out.printf("成绩第二好的人的姓名为%s,学号为%dn", l.get(1).name, l.get(1).id);
System.out.printf("成绩最差的人的姓名为%s,学号为%dn", 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,成绩为%.2fn", 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,成绩为%.2fn", 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方法的全部内容,希望文章能够帮你解决Java 可用于比较与排序的lambda表达式和comparing方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复