【问题标题】:Remove items from inner list从内部列表中删除项目
【发布时间】:2020-12-12 09:39:10
【问题描述】:

我有一个部门列表和地址列表。每个地址都有一个带有起始日期的句点。 以下代码在每个部门中查找具有最新日期的地址并删除所有其他地址。它似乎有效,但我相信它可以以更优雅的方式完成。有什么建议吗?

List<Department> departments = fetchDepartments();

departments.forEach(department -> {
  
  Date fromDate = department.getAddresses().stream().map(address -> 
  address.getPeriod().getFromDate()).max(Date::compareTo).get();
            
  department.setAddresses(department.getAdresses().stream()
    .filter(address -> address.getPeriod().getDateFrom().equals(fromDate))
    .collect(Collectors.toList()));
});

【问题讨论】:

  • 返回的值是getFromDate 唯一的吗?或者新地址可以不止一个?

标签: java list filter


【解决方案1】:

您的代码一开始就不起作用(您有一个设置器),那么为什么要在这里使用相当笨拙的.forEach 终端呢?它不是更短,你一无所获,而且你失去了异常透明度、局部变量透明度和控制流透明度。

当有 2 种方法可以做一件事,而这两种方法中的一种方法严格来说能力较差时,请不要使用它。此外,如果任何部门内部地址为零,您的代码将失败;在这种情况下,正确的做法肯定是干脆什么都不做。此外,如果有 2 个以上的地址具有相同的“起始日期”,则将它们全部保存。这是故意的还是您更愿意选择任意一个。

for (Department d : fetchDepartments()) {
  var addresses = department.getAddresses();
  if (addresses.size() < 2) continue;
  var address = addresses.stream()
    .max(Comparator.comparing(a -> a.getPeriod().getFromDate()))
    .get();
  department.setAddresses(List.of(address));
}

这可以做更多的事情(例如,如果一开始就没有一点,就避免一堆步法,并避免例外)。

尽管它做得更多,但它也明显更短。

【讨论】:

    【解决方案2】:

    您可以使用TreeMap 来收集有关其fromDate 的地址,因为TreeMap 会自动排序,您可以检索最后一个键,即最高的键

    for (Department department : departments) {
        TreeMap<Date, List<Adress>> fromDate = new TreeMap<>(department.getAdresses().stream()
            .collect(Collectors.groupingBy(adress -> adress.getPeriod().getFromDate())));
    
        department.setAdresses(fromDate.lastEntry().getValue());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-20
      • 1970-01-01
      • 2016-05-08
      • 2011-03-18
      • 1970-01-01
      • 2020-06-18
      相关资源
      最近更新 更多