【问题标题】:How do I convert following code to streams如何将以下代码转换为流
【发布时间】:2017-12-01 06:15:12
【问题描述】:

我有一个列表,如何将其转换为可以将具有最小值的键作为键值对的 Map。我想将此代码转换为流。

Map<Long, Date> formToDate = new HashMap<>();
    for(FormInstance formInstance : formInstances) {
        if(formToDate.get(formInstance.getForm().getId()) == null) {
            formToDate.put(formInstance.getForm().getId(), formInstance.getCreatedDate());
        }
        else{
            Date prevDate = formToDate.get(formInstance.getForm().getId());
            Date thisDate = formInstance.getCreatedDate();
            formToDate.put(formInstance.getForm().getId(), prevDate.before(thisDate) ? prevDate : thisDate);
        }
    }

到这样的事情:

Map<Long, List<Date>> formToDate = formInstances.stream()
            .collect(
                    Collectors.groupingBy(formInstance -> formInstance.getForm().getId(),
                            Collectors.mapping(FormInstance::getCreatedDate, Collectors.toList())));

但我不想返回列表,而是希望有最小的日期。

【问题讨论】:

标签: java lambda java-8 stream java-stream


【解决方案1】:

有一个Collector::toMap 实现,它提供了一个合并功能。这可用于从具有相同 id 的两个不同条目中确定最小日期,例如:

Map<Long, Date> minimum = formInstances.stream().collect(Collectors.toMap(
        fi -> fi.getForm().getId(), 
        FormInstance::getCreatedDate, 
        (date, date2) -> date.before(date2) ? date : date2
));

【讨论】:

    【解决方案2】:

    如果您真的想使用流,Flown 的回答很好,但通常可以不使用流,同时仍然利用较新的 Java 功能。我见过很多案例(包括我自己),其中使用流是为了使用流,而不是采用更简单、更直接的方法。

    如果你已经有一个列表并且不想创建一个流,你可以使用新的Map.merge() 方法:

    Map<Long, Date> minimum = new HashMap<>();
    forms.forEach(form -> minimum.merge(form.getForm().getId(),
                                        form.getCreatedDate(),
                                        (date, date2) -> date.before(date2) ? date : date2));
    

    除了mergeMap 有许多方法可以使这样的事情变得更容易:computeIfAbsentgetOrDefault,甚至“旧”的containsKey 方法可以通过替换使代码更具可读性常见的样板 sn-ps,就像您使用的那样:

    if (map.get(key) == null) { add } else { test and put }

    【讨论】:

      【解决方案3】:

      另一种选择是将Collectors.groupingBy 结合使用Collectors.mappingCollectors.minBy

      Map<Long, Optional<Date>> formToDate =
          formInstances.stream()
                       .collect(Collectors.groupingBy(fi -> fi.getForm().getId(),
                                                      Collectors.mapping(FormInstance::getCreatedDate,
                                                                         Collectors.minBy(Date::compareTo))));
      

      【讨论】:

        猜你喜欢
        • 2019-08-16
        • 1970-01-01
        • 2018-04-27
        • 2021-08-24
        • 1970-01-01
        • 1970-01-01
        • 2014-03-18
        • 2022-01-15
        • 2021-08-28
        相关资源
        最近更新 更多