使用日期 属性 in Java 比较同一列表中的两个 POJO 对象 8

Compare two POJO objects in the same list using date property in Java 8

我有一个员工 POJO class,它有一个 属性 日期。我必须比较 POJO 对象并找出具有相同名称和最新日期的 Employee 并收集到不同的列表。 我正在尝试使用 Java 8 的 isBefore() 和 isAfter() 方法来做到这一点,但直到现在都不成功。

public class Employee {
       private LocalDate date;
       private String name;
}
Employee Objects:
  ["John", 2022-02-07]
  ["John", 2022-02-17]
  ["Mike", 2022-01-19]

这是一个员工对象列表。因此,根据任务 ["John", 2022-02-17] 应该收集。

我可以使用 min/max 和比较器得到结果,但尝试使用 isAfter() 和 isBefore() 来解决它。

要执行此操作,您必须执行以下步骤:

  1. 按结果 Map<String, List<Employee>> 的名称分组
  2. 将每个 List<Employee> 减少到一个 Employee
  3. select 拥有最大日期的员工
Map<String, Optional<Employee>> mapResult = employees.stream()
        .collect(
            Collectors.groupingBy(Employee::getName, // 1
                Collectors.reducing( // 2
                    BinaryOperator.maxBy(Comparator.comparing(Employee::getDate)) // 3
                )
            )
        );

示例输入:

["John", 2022-02-07]
["John", 2022-02-17]
["Mike", 2022-01-19]
["Mike", 2022-03-17]

示例输出:

["John", 2022-02-17]
["Mike", 2022-03-17]

这可能是一个选项:

Map<String, Employee> map = employees.stream()
    .collect(groupingBy(
        Employee::name,
        collectingAndThen(
            reducing((a, b) -> a.date.isAfter(b.date) ? a : b),
            Optional::get
        )
    ));

事情是这样的:

首先,我们按 name 分组,这会产生 name => list[date] 映射。然后我们缩减列表以获得单个值,将列表中的每个元素与日期与后续元素进行比较。使用 isAfter.

进行比较

collectionAndThen(…, Optional::get) 部分存在是因为 reducing returns 是 Optional<E> 而不是 E。但是 groupingBy 向我们保证每个列表至少包含一个元素。