我是靠谱客的博主 追寻百合,最近开发中收集的这篇文章主要介绍Java 可用于比较与排序的lambda表达式和comparing方法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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方法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部