我对Java 8流完全陌生,并且尝试获取以下描述的行为:

class myVO {
    Long id;
    BigDecimal value;
    Date date;
    getter/setter
}

myVO method(Map<Long, myVO> inputMap) {
    return inputMap.stream()
                   .filter(x -> x.getValue().compareTo(BigDecimal.ZERO) > 0)
                   .sorted(); //FIXME
}


我只想获取一个myVO obj,它是具有相同日期(最低的)的记录的BigDecimal值的总和。

例如

xL, 10, 2015/07/07
xL, 15, 2015/07/08
xL, 20, 2015/07/07
xL, 25, 2015/07/09


结果

xL, 30, 2015/07/07


N.B. id(xL)不是重要字段。

更新-已采用的解决方案(尽管不是单次通过)

if(null != map && !map.isEmpty()) {
        Date closestDate = map.values().stream()
                .filter(t -> t.getDate() != null)
                .map(MyVO::getDate)
                .min(Comparator.naturalOrder()).orElse(null);
        myVO.setDate(closestDate);

        BigDecimal totalValue = map.values().stream()
                .filter(x -> x.getValue() != null && x.getValue().signum() != 0)
                .filter(t -> t.getDate().equals(closestDate))
                .map(MyVO::getValue)
                .reduce(BigDecimal::add).orElse(null);
        myVO.setValue(totalValue != null ? totalValue.setScale(2, BigDecimal.ROUND_HALF_DOWN) : totalValue);
    }

最佳答案

考虑到inputMap至少有一个条目,可以这样完成:

myVO method(Map<Long, myVO> inputMap) {
    Date minDate = inputMap.values().stream().map(myVO::getDate).min(Comparator.naturalOrder()).get();

    BigDecimal sum = inputMap.values().stream().filter(t -> t.getDate().equals(minDate)).map(myVO::getValue).reduce(BigDecimal::add).get();

    myVO myVOObj = new myVO();
    myVOObj.setDate(minDate);
    myVOObj.setValue(sum);
    myVOObj.setId(??);

    return myVOObj;
}

07-26 00:52