从列表中删除重复条目并保留最后更新的条目 LocalDate

Remove duplicate entries from a list and keep last updated entry LocalDate

我有一名员工 class 具有以下字段。

class Employee {
    final int id;
    final String name;
    final LocalDate updatedDate;
    // setters and getters
}

我有一个员工列表,该列表可能包含具有不同 updatedDate 的重复员工。现在我想创建一个集合,使每个 employeeId 都有一个唯一的条目。如果有重复条目,应保留最新的updatedDate

我想出了下面的解决方案,基于 updatedDate 排序并添加它 TreeSet 以保持 Id 的唯一性。我可以通过在 Employee.

中实现 hashcode & equals 来使用 HashSet
List<Employee> employees = new ArrayList<>();

// sort
List<Employee> sortedList = employees.stream()
       .sorted(Collections.reverseOrder(Comparator.comparing(employee -> employee.updatedDate)))
       .collect(Collectors.toList());

Set<Employee> employeeSet = new TreeSet<>(Comparator.comparing( employee -> employee.id));
sortedList.forEach(employeeSet::add);

现在的问题是,大多数时候员工列表将包含唯一元素。很少会有重复条目。仅存在唯一条目时的排序将无法很好地扩展。有没有办法通过避免排序来改进上述解决方案?

这个问题的另一种方法是使用 groupingBy 收集器,然后使用 collectingAndThen 收集器找到最新的 updatedDate。 我认为这种方式更具可读性和清洁性。

为了简化,我将收集器导入为静态。

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.maxBy;
import static java.util.stream.Collectors.groupingBy;

Collection<Employee> collection = employees.stream()
         .collect(groupingBy(Employee::getId,
             collectingAndThen(maxBy(Comparator.comparing(Employee::getUpdatedDate)),
                            employee -> employee.orElse(null)))).values();

然后

List<Employee> result = new ArrayList<>(collection);

接受的答案可以进一步简化为

 Collection<Employee> collection = employees.stream()
    .collect(Collectors.toMap(Employee:: getId, Function.identity(),
        BinaryOperator.maxBy(Comparator.comparing(Employee:: getUpdatedDate)))).values();