Solo  当前访客:1 登录 注册

Java8特性详解--Lambda表达式之排序 有更新!

前言

java9都要发布了,java8的一些特性你们掌握了吗?
今天给大家带来的是java8核心特性之一的Lambda表达式在数组/集合排序中的应用.

正文

首先,为本文创建一个测试类:

public class Student implements Comparable<Student> {
    private int age;
    private String nameEn;
    private int grade;

    public Student(int age, String nameEn, int grade) {
        this.age = age;
        this.nameEn = nameEn;
        this.grade = grade;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getNameEn() {
        return nameEn;
    }

    public void setNameEn(String nameEn) {
        this.nameEn = nameEn;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

    public static int compare(Student s1, Student s2) {
        return Integer.compare(s1.getAge(), s2.getAge());
    }

    @Override
    public int compareTo(Student s) {
        return Integer.compare(this.getAge(), s.getAge());
    }
}
...
    /**
     * 初始化数据
     *
     * @return
     */
    public static List<Student> initData() {
        List<Student> list = new ArrayList<>();
        list.add(new Student(11, "zhangsan", 5));
        list.add(new Student(12, "lisi", 5));
        list.add(new Student(9, "wangwu", 6));
        list.add(new Student(13, "zhaoliu", 6));
        list.add(new Student(8, "tianqi", 3));
        list.add(new Student(6, "wangba", 1));
        list.add(new Student(8, "jiujiu", 2));
        return list;
    }
...

传统排序方式

1.在Java 8之前,对集合进行排序要为Comparator创建一个匿名内部类用来排序,比如,按照age字段从小到大排序:

    /**
     * 传统匿名内部类比较器
     */
    @Test
    public void soreted1() {
        List<Student> list = Java8SortedDemo.initData();
        list.sort(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                return Integer.compare(s1.getAge(), s2.getAge());
            }
        });
        Assert.assertEquals(list.get(0).getNameEn(), "wangba");
    }

2.或者让Student实现Comparable接口,复写compareTo方法,同样按照age字段从小到大排序:

...
    @Override
    public int compareTo(Student s) {
        return Integer.compare(this.getAge(), s.getAge());
    }
...

    /**
     * 实现Comparable接口
     */
    @Test
    public void soreted2() {
        List<Student> list = Java8SortedDemo.initData();
        Collections.sort(list);
        Assert.assertEquals(list.get(0).getNameEn(), "wangba");
    }

java8排序方式

3.在java8中引入了重要的特性之一lambda,根据Lambda表达式的介绍,我们现在可以不使用匿名内部类,只使用简单实用的语义就可以得到相同的结果,按照age字段从小到大排序:

    /**
     * java8的Lambda,显式指定比较类型
     */
    @Test
    public void soreted3() {
        List<Student> list = Java8SortedDemo.initData();
        list.sort((Student s1, Student s2) -> Integer.compare(s1.getAge(), s2.getAge()));
        Assert.assertEquals(list.get(0).getNameEn(), "wangba");
    }

4.我们甚至可以省略类型,让编译器自行推测,按照age字段从小到大排序:

    /**
     * java8的Lambda,不指定比较类型
     */
    @Test
    public void soreted4() {
        List<Student> list = Java8SortedDemo.initData();
        list.sort((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge()));
        Assert.assertEquals(list.get(0).getNameEn(), "wangba");
    }

5.我们还可以使用静态方法排序,按照age字段从小到大排序:

...
    public static int compare(Student s1, Student s2) {
        return Integer.compare(s1.getAge(), s2.getAge());
    }
...

    /**
     * 自定义静态方法
     */
    @Test
    public void soreted5() {
        List<Student> list = Java8SortedDemo.initData();
        list.sort(Student::compare);
        Assert.assertEquals(list.get(0).getNameEn(), "wangba");
    }

6.当然,java8为我们准备好了通用的Comparator.comparing方法,按照age字段从小到大排序:

    /**
     * Comparator提供的静态方法
     */
    @Test
    public void soreted6() {
        List<Student> list = Java8SortedDemo.initData();
        list.sort(Comparator.comparing(Student::getAge));
        Assert.assertEquals(list.get(0).getNameEn(), "wangba");
    }

java8排序方法拓展:

java8同样让我们具备编写更复杂逻辑排序的方法表达式,

7.比如,反转排序,按照age字段从大到小排序:

    /**
     * 反转排序
     */
    @Test
    public void soreted7() {
        List<Student> list = Java8SortedDemo.initData();
        list.sort(Comparator.comparing(Student::getAge).reversed());
        Assert.assertEquals(list.get(0).getNameEn(), "zhaoliu");
    }

8.比如,多字段组合排序,先按照grade从大到小,相同则按照age从大到小排序:

    /**
     * 多字段组合排序(匿名类方式)
     */
    @Test
    public void soreted8() {
        List<Student> list = Java8SortedDemo.initData();
        list.sort((s1, s2) -> {
            if (Integer.compare(s1.getGrade(), s2.getGrade()) != 0) {
                return Integer.compare(s2.getGrade(), s1.getGrade());
            }
            return Integer.compare(s2.getAge(), s1.getAge());
        });
        Assert.assertEquals(list.get(0).getNameEn(), "zhaoliu");
    }

9.java8的Comparator为我们准备了更便利的链式风格组合排序方式,先按照grade从大到小,相同则按照age从小到大排序:

    /**
     * 多字段组合排序(链式接口)
     */
    @Test
    public void soreted9() {
        List<Student> list = Java8SortedDemo.initData();
        list.sort(Comparator.comparing(Student::getGrade).reversed().thenComparing(Student::getAge));
        Assert.assertEquals(list.get(0).getNameEn(), "wangwu");
    }

总结

Lambda表达式虽然不是什么新鲜玩意了,但是灵活使用java8提供的语法糖,能让你书写出更简洁,语义化的代码…
本文所示demo已经上传github,各位随时可以下载查阅:Java8特性详解–Lambda表达式之排序

17-08-30 15:28 washmore
标签: , , , ,
washmore
17-08-30 10:53 回复»

看使用场景吧,不仅仅是自己用的爽,也要让同事看得爽,我司目前使用jdk8,因此大家或多或少倾向于使用这些东西,当然 如果还在jdk6时代的童鞋,这些语法糖也没法用.

wizardforcel
17-08-30 10:22 回复»

eta 表示法真是太好用了╮(╯_╰)╭

validate
TOP