Java8-Stream多个字段排序

By | 2022年2月16日

Sorting List and Stream on Multiple Fields Java 8 Example

这篇文章将学习如何使用 Java 8 对列表执行排序并在多个字段上进行流式处理。

简要说明

我们使用 Comparators 和 Comparator.thenComparing() 方法使用多个字段对流和对象列表执行排序。 此方法返回一个字典顺序比较器和另一个比较器。 如果你对 SQL 有所了解,那么简单理解这种方法与 SQL group by 子句的效果是一样的。

创建比较器

需要注意的是,要对多个字段执行排序,首先我们为要执行排序的每个字段创建比较器。 然后我们以所需的顺序链接每个比较器,以通过对完整排序的影响来给出和实现组。

//first name comparator
Comparator<Employee> compareByFirstName = Comparator.comparing( Employee::getFirstName );
 
//last name comparator
Comparator<Employee> compareByLastName = Comparator.comparing( Employee::getLastName );
 
//Compare by first name and then last name (multiple fields)
Comparator<Employee> compareByFullName = compareByFirstName.thenComparing(compareByLastName);
 
//Using Comparator - pseudo code
list.stream().sorted( comparator ).collect();

我们有一个 Employee 类,它具有三个字段 id、firstName 和 lastName。 首先,我们为 firstName 创建一个比较器,然后为 lastName 创建另一个比较器。

然后我们通过比较 firstName 和 lastName 对 firstName 和 lastName 字段进行排序。

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

class Employee {

  private Long id;

  private String firstName;

  private String lastName;

  public Employee() {

  }

  public Employee(Long id, String firstName, String lastName) {
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
  }

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  @Override
  public String toString() {
    return "Employee{" +
        "id=" + id +
        ", firstName='" + firstName + '\'' +
        ", lastName='" + lastName + '\'' +
        '}';
  }
}

public class SortingMultipleFields {

  public static void main(String[] args) {
    ArrayList<Employee> employees = getUnsortedEmployeeList();

    //Compare by first name and then last name
    Comparator<Employee> compareByName = Comparator
        .comparing(Employee::getFirstName)
        .thenComparing(Employee::getLastName);

    List<Employee> sortedEmployees = employees.stream()
        .sorted(compareByName)
        .collect(Collectors.toList());

    for (Employee employee : sortedEmployees) {
      System.out.println(employee.getId() + " " + employee.getFirstName() + " " + employee.getLastName());
    }
  }

  private static ArrayList<Employee> getUnsortedEmployeeList() {
    ArrayList<Employee> list = new ArrayList<>();
    list.add(new Employee(2l, "Lokesh", "Gupta"));
    list.add(new Employee(1l, "Alex", "Hales"));
    list.add(new Employee(4l, "Brian", "Lara"));
    list.add(new Employee(5l, "Nisham", "Jimmy"));
    list.add(new Employee(3l, "David", "Beckham"));
    list.add(new Employee(7l, "Alex", "Ferguison"));
    list.add(new Employee(6l, "Brian", "Tom"));
    return list;
  }
}
// 输出
7 Alex Ferguison
1 Alex Hales
4 Brian Lara
6 Brian Tom
3 David Beckham
2 Lokesh Gupta
5 Nisham Jimmy