Java 8 Lambda : Comparator 示例

来源:
三产
最后修订:
2017年04月26日 12:18:52
 382
在这个例子中,我们将向您展示如何使用 Java 8 Lambda 表达式来编写 `Comparator` 对 `List` 进行排序。

英文原文:Java 8 Lambda : Comparator 示例本文是在该文基础上翻译以及部分修改

Developer.java

import java.math.BigDecimal;

/**
 * <p> Developer </p>
 *
 * @author 三产
 * @version 1.0
 * @date 2017-04-26
 * @QQGroup 213732117
 * @website http://www.coderknock.com
 * @copyright Copyright 2017 拿客 coderknock.com  All rights reserved.
 * @since JDK 1.8
 */
public class Developer {

    String name;
    BigDecimal salary;
    int age;

    public Developer(String name, BigDecimal salary, int age) {
        this.name = name;
        this.salary = salary;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Developer [" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                ", age=" + age +
                ']';
    }
}

经典 Comparator 示例:

Comparator<Developer> byName = new Comparator<Developer>() {
            @Override
            public int compare(Developer developer, Developer compareDeveloper) {
                return developer.getName().compareTo(compareDeveloper.getName());
            }
        };

对应的 Lambda 表达式示例:

 Comparator<Developer> byNameLambda =
   (Developer developer, Developer compareDeveloper)->developer.getName().compareTo(compareDeveloper.getName());

Java8更简洁的一种写法:

Comparator<Developer> byNameLambdaSimple = Comparator.comparing(Developer::getName);

1.不用Lambda排序

比较 Developer的对象的 age 的示例。通常使用 Collections.sort 并传递一个这样的匿名Comparator类:

TestSorting.java

package com.mkyong.java8;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class TestSorting {

    public static void main(String[] args) {

        List<Developer> listDevs = getDevelopers();

        System.out.println("Before Sort");
        for (Developer developer : listDevs) {
            System.out.println(developer);
        }

        //sort by age
        Collections.sort(listDevs, new Comparator<Developer>() {
            @Override
            public int compare(Developer o1, Developer o2) {
                return o1.getAge() - o2.getAge();
            }
        });

        System.out.println("After Sort");
        for (Developer developer : listDevs) {
            System.out.println(developer);
        }

    }

    private static List<Developer> getDevelopers() {

        List<Developer> result = new ArrayList<Developer>();

        result.add(new Developer("mkyong", new BigDecimal("70000"), 33));
        result.add(new Developer("alvin", new BigDecimal("80000"), 20));
        result.add(new Developer("jason", new BigDecimal("100000"), 10));
        result.add(new Developer("iris", new BigDecimal("170000"), 55));

        return result;

    }

}

输出

Before Sort
Developer [name=mkyong, salary=70000, age=33]
Developer [name=alvin, salary=80000, age=20]
Developer [name=jason, salary=100000, age=10]
Developer [name=iris, salary=170000, age=55]

After Sort
Developer [name=jason, salary=100000, age=10]
Developer [name=alvin, salary=80000, age=20]
Developer [name=mkyong, salary=70000, age=33]
Developer [name=iris, salary=170000, age=55]

当排序要求更改时,您只需传递另一个新的匿名Comparator类:

//sort by age
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getAge() - o2.getAge();
    }
});

//sort by name
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getName().compareTo(o2.getName());
    }
});

//sort by salary
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getSalary().compareTo(o2.getSalary());
    }
});

它是有效的,但是你不认为仅仅因为要改变一行代码创建一个类是有点奇怪的么?

2.用Lambda排序

在Java 8中,List 接口支持直接使用 sort 该方法,不再需要使用 Collections.sort 了。

//List.sort() since Java 8
listDevs.sort(new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o2.getAge() - o1.getAge();
    }
});

Lambda表达式示例:

TestSorting.java

package com.mkyong.java8;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class TestSorting {

    public static void main(String[] args) {

        List<Developer> listDevs = getDevelopers();

        System.out.println("Before Sort");
        for (Developer developer : listDevs) {
            System.out.println(developer);
        }

        System.out.println("After Sort");

        //lambda here!
        listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());

        //java 8 only, lambda also, to print the List
        listDevs.forEach((developer)->System.out.println(developer));
    }

    private static List<Developer> getDevelopers() {

        List<Developer> result = new ArrayList<Developer>();

        result.add(new Developer("mkyong", new BigDecimal("70000"), 33));
        result.add(new Developer("alvin", new BigDecimal("80000"), 20));
        result.add(new Developer("jason", new BigDecimal("100000"), 10));
        result.add(new Developer("iris", new BigDecimal("170000"), 55));
-
        return result;

    }

}

输出

Before Sort
Developer [name=mkyong, salary=70000, age=33]
Developer [name=alvin, salary=80000, age=20]
Developer [name=jason, salary=100000, age=10]
Developer [name=iris, salary=170000, age=55]

After Sort
Developer [name=jason, salary=100000, age=10]
Developer [name=alvin, salary=80000, age=20]
Developer [name=mkyong, salary=70000, age=33]
Developer [name=iris, salary=170000, age=55]

3.更多Lambda的例子

3.1按年龄排序

//sort by age
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getAge() - o2.getAge();
    }
});

//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());

//lambda, valid, parameter type is optional
listDevs.sort((o1, o2)->o1.getAge()-o2.getAge());
// lambda
listDevs.sort(Comparator.comparing(Developer::getAge));

3.2按名称排序

//sort by name
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getName().compareTo(o2.getName());
    }
});

//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getName().compareTo(o2.getName()));

//lambda
listDevs.sort((o1, o2)->o1.getName().compareTo(o2.getName()));
// lambda
listDevs.sort(Comparator.comparing(Developer::getName));

3.3按薪水排序

//sort by salary
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getSalary().compareTo(o2.getSalary());
    }
});

//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getSalary().compareTo(o2.getSalary()));

//lambda
listDevs.sort((o1, o2)->o1.getSalary().compareTo(o2.getSalary()));
// lambda
listDevs.sort(Comparator.comparing(Developer::getSalary));

3.4 反转排序

3.4.1使用Lambda表达式对列表进行工资由少到多的排序。

Comparator<Developer> salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());
listDevs.sort(salaryComparator);

输出

Developer [name=mkyong, salary=70000, age=33]
Developer [name=alvin, salary=80000, age=20]
Developer [name=jason, salary=100000, age=10]
Developer [name=iris, salary=170000, age=55]

3.4.2使用Lambda表达式对列表进行工资由多到少的排序。

Comparator<Developer> salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());
listDevs.sort(salaryComparator.reversed());

输出

Developer [name=iris, salary=170000, age=55]
Developer [name=jason, salary=100000, age=10]
Developer [name=alvin, salary=80000, age=20]
Developer [name=mkyong, salary=70000, age=33]

参考文献

  1. 开始使用Java Lambda表达式
  2. Oracle:Lambda表达式
  3. Oracle:比较器