Java 排序逻辑和识别两个对象的最大值

Java Sorting logic and Identifying max of two objects

要求是找到部门 2 组号 8 和部门 2 组号 4 的最新员工对象(最新日期)。同理,部门 1 组号 8 和部门 1 组号 4。我只需要最终列表中以上所有对象中的最新一个对象。

写的比较逻辑是按照需要的顺序排序,只保留需要的对象。但是我被困住了,因为我找不到从排序列表中保留单个对象的方法。无论如何我可以实现它吗?忽略比较器逻辑,如果您可以建议使用流或其他良好实现的任何 ootb 方式,我将不胜感激?

  SimpleDateFormat df = new SimpleDateFormat("dd-mm-yyyy");
    List<Employee> employees = new LinkedList<Employee>(Arrays.asList(
        new Employee("Emp1", df.parse("12-08-2020"),
            new EmpType("1", new Group(8))),
        new Employee("Emp2", df.parse("11-08-2020"),
            new EmpType("2", new Group(8))),
        new Employee("Emp3", df.parse("10-08-2020"),
            new EmpType("2", new Group(4))),
        new Employee("Emp4", df.parse("17-08-2020"),
            new EmpType("2", new Group(8))),
        new Employee("Emp5", df.parse("19-08-2020"),
            new EmpType("1", new Group(4)))));


    /* Sorting logic to sort by group number first then by department and then by date */
    Collections.sort(employees, new Comparator<Employee>() {
      @Override
      public int compare(Employee employee, Employee t1) {
        int val = 0;
        if (employee.getEmpType().getGroup().getNumber() < t1.getEmpType().getGroup().getNumber()) {
          val = 1;
        } else if (employee.getEmpType().getGroup().getNumber() > t1.getEmpType().getGroup()
            .getNumber()) {
          val = -1;
        } else {
          val = 0;
        }

        if (val == 0) {
          val = -(employee.getEmpType().getDepartment().compareTo(t1.getEmpType().getDepartment()));
        }
        if (val == 0) {
          val = -employee.getDate().compareTo(t1.getDate());
        }
        return val;
      }
    });

您可以将 Collections.max 与您已实现的 Comparator 一起使用,而不是排序。

编辑以解决评论中的讨论:
如果我正确理解数据结构,EmpType 封装了我们想要为其找到“最新”员工的唯一组合。假设它正确实现了 equals(Object)hashCode() 方法,您可以流式传输列表并将其收集到从 EmpType 到最新员工的映射:

Map<EmpType, Employee> latestEmployees =
    employees.stream()
             .collect(Collectors.toMap(
                          Employee::getEmpType,
                          Function.identity(),
                          BinaryOperator.maxBy(
                              Comparator.comparing(Employee::getDate))));

我觉得把业务逻辑混在排序函数里面很乱。

为什么不根据员工的日期对员工进行降序排序并解析结果数组,直到第一次满足您的条件?

您可以使用 Stream API 的 Collectors.toMapEmpType 进行映射,并使用 BinaryOperator.maxBy 获取具有相同 EmpType 的每个组的最新日期作为价值观。然后获取newArrayList中map的值。这里按 EmpType 映射,因为它包含组号和部门,您需要 EmpType.

的适当等号和哈希码实现
List<Employee> res = new ArrayList(employees.stream()
    .collect(Collectors.toMap(Employee::getEmpType, Function.identity(),
        BinaryOperator.maxBy(Comparator.comparing(Employee::getDate)))).values());

或者您可以创建一对组号和部门,如 new AbstractMap.SimpleEntry(e.getEmpType().getDepartment(), e.getEmpType().getGroup().getNumber()) 作为键而不是 EmpType 然后不需要 equals 和 hashcode 实现

List<Employee> res = new ArrayList(employees.stream()
        .collect(Collectors.toMap(
                         e -> new AbstractMap.SimpleEntry(e.getEmpType().getDepartment(),
                                                  e.getEmpType().getGroup().getNumber()),
                                  Function.identity(),
                        BinaryOperator.maxBy(Comparator.comparing(Employee::getDate))))
        .values());