【问题标题】:filter list of Objects java stream过滤对象 java 流的列表
【发布时间】:2017-02-08 06:32:01
【问题描述】:

我想从列表中过滤基于员工的记录。

我的员工对象看起来像

<pre>new Employee(EmpID, EmpName,"month-year",Transition)

我可以为每个员工拥有多个具有不同转换和月份年份的对象,例如 &lt;pre&gt;Hired , Bench, joinedproject,releasedproject,resign 和相应的日期

现在我想从每个员工的第一个和最后一个对象中获取月份。

例如

<pre>new Employee(1, "alex","02-2016","Hired")
new Employee(1, "alex","02-2016","Bench")
new Employee(1, "alex","03-2016","Project")
new Employee(1, "alex","12-2016","Resign")
new Employee(1, "alex","01-2017","Exit")

对于上面的例子,我会得到日期为“02-2016”和“01-2017”

我希望我的问题很清楚。

任何指针将不胜感激。

【问题讨论】:

  • 我想你的month-yearString,它总是采用00-00 的格式吗? 1 月 0 日还是 1 日?是终止日期还是雇用日期?
  • 是的,我的日期是字符串和它的 1-2016 格式。一月是 1
  • 还需要一些精度...当您说“3 个月的周期”时,您到底想要什么?过去三个月内?
  • 我想从列表中删除在 3 个月内加入和离开的员工。我正在尝试检查公司员工的季度退出情况。有多少员工在 3 个月内加入和离开公司
  • Collection.removeIf()Stream.filter()

标签: java java-8 java-stream


【解决方案1】:

这应该可以解决您的问题:

List<Employee> list = ...

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .appendPattern("MM-yyyy")
    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
    .toFormatter();
list.removeIf(e -> LocalDate.parse(e.getHiringDate(), formatter)
    .until(LocalDate.parse(e.getTerminationDate(), formatter)).getMonths() < 3);

开头长的builder调用是因为LocalDate.parse不能实例化LocalDate没有一个月中的一天,所以我们必须指定一个默认的日期(在本例中为1)。

注意:从您的问题中不清楚您的 Employee 类的结构是什么,所以我假设它符合 JavaBeans 模式并为 HiringDateTerminationDate 属性提供 getter .尽管如此,如果您的结构与我的不同,您应该能够将此解决方案应用于您现有的代码。

【讨论】:

  • 您好,我已经为我的问题格式化并添加了详细示例。请您重新打开我的问题。
  • 如果需要解析年月字段,为什么不直接使用YearMonth.parse("02-2016", "MM-uuuu")呢?对我来说似乎更简单,无需为每月的哪一天烦恼。
  • @OleV.V.这确实是一个更好的主意。我根本不知道YearMonth。我不想把你的想法归功于你,所以我会把它留在 cmets 中。
【解决方案2】:

仅获取您可能执行的每个员工的第一个月和最后一个月的年份字符串(使用 Java 8 流):

    String[][] monthYears = employeeTransitions.stream()
            .collect(Collectors.groupingBy(Employee::getId))
            .values()
            .stream()
            .map(transList -> new String[]{ transList.get(0).getMonthYear(), 
                    transList.get(transList.size() - 1).getMonthYear() })
            .toArray(String[][]::new);

我在您的列表中添加了一个 Employeenew Employee(2, "mks", "02-2017", "Hired"),以便使用多个员工 ID 对其进行测试。上面的代码现在产生:

[[02-2016, 01-2017], [02-2017, 02-2017]]

我们在这里注意到两件事:与员工 ID 没有耦合。对于我在列表中仅添加一条记录的员工,我得到与第一个和最后一个相同的月份-年份字符串,我认为这没问题。

将月份与员工 ID 关联起来并不复杂:

    Map<Integer, List<String>> monthYearPerEmployee = employeeTransitions.stream()
            .collect(Collectors.groupingBy(Employee::getId))
            .entrySet()
            .stream()
            .collect(Collectors.toMap(Map.Entry::getKey, entry -> {
                 List<Employee> transitionsForEmployee = entry.getValue();
                 return Arrays.asList(transitionsForEmployee.get(0).getMonthYear(), 
                         transitionsForEmployee.get(transitionsForEmployee.size() - 1).getMonthYear());
            }));

现在我们得到:

{1=[02-2016, 01-2017], 2=[02-2017, 02-2017]}

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 2022-01-12
    相关资源
    最近更新 更多