【问题标题】:Java Sorting logic and Identifying max of two objectsJava排序逻辑和识别两个对象的最大值
【发布时间】:2020-12-30 17:07:42
【问题描述】:

要求是找到最新的员工对象(最新日期),其组号为 8 和部门 2,组号 4 在部门 2 中。同样的方法是部门 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;
      }
    });

【问题讨论】:

  • 你需要最新的员工意味着只有最新的日期吗?
  • 谢谢罗诺。我实际上并没有从列表中寻找最大值。与原始描述一样,我需要每个条件的最新一个对象,其中组为 8,部门为 2,日期最晚,然后组为 4,部门 2 的日期最晚。那么组是 8 个部门 1 的最新日期,组是 4 个部门 1 的最新日期。
  • 您需要为每种情况分别提供最新的吗?还是只有一个?
  • 没错,Rono,需要在同一个最终列表中的每个条件中的最新一个。

标签: java sorting arraylist comparator


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢穆雷尼克。我实际上并没有从列表中寻找最大值。与原始描述一样,我需要每个条件的最新一个对象,其中组为 8,部门为 2,日期最晚,然后组为 4,部门 2 的日期最晚。那么组是 8 个部门 1 的最新日期,组是 4 个部门 1 的最新日期。
  • @vipinev 这四个分类是任意的,还是您想根据组和部门的独特组合找到最新的员工?
  • 所以这些不是任意的。这是正确的。需要每个组和部门的唯一组合的最新员工(日期)。
  • 非常感谢。我认为这项工作与基于部门和组号的 equals 实现一起工作。非常感谢您熟悉这个概念。
【解决方案2】:

您可以使用 Stream API 的Collectors.toMap 来映射EmpType,并使用BinaryOperator.maxBy 作为值获取具有相同EmpType 的每个组的最新日期。然后在新的ArrayList 中获取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 然后不需要等号和哈希码实现

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());

【讨论】:

  • 优秀的方法!我认为抽象地图实现做到了,而且看起来也很整洁。非常感谢罗诺!我想我会去的。
【解决方案3】:

我发现在排序函数中混合业务逻辑很麻烦。

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

【讨论】:

  • 感谢您的建议。我可以,但是需要很多条件逻辑吗?所以很想知道我是否可以遵循任何简洁的实现?
  • 它将排序功能简化为单行,然后您只需要编写一个带有 if (带有您的长条件)和内部 break 的 foreach 。排序是通用的,排序函数必须遵守一些条件,例如:如果a &lt; bb &lt; c,那么a &lt; c。在这样的函数中混合业务逻辑可能会破坏这些规则并导致错误的实现。
猜你喜欢
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-11
  • 1970-01-01
  • 2018-07-17
相关资源
最近更新 更多