public List<UserFundsDto> aggregate(final List<FundsByFunderDto> fundsByFunder) { return fundsByFunder.stream() .collect(Collectors.groupingBy(funds -> funds.getFunderAddress().toLowerCase() + funds.getFunderUserId(), Collectors.mapping(mapToUserFundDto(), Collectors.reducing(mergeFundsAndRefunds())))) .values() .stream() .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); }
private BinaryOperator<FundsByFunderDto> sumFunds() { return (fundsByFunder1, fundsByFunder2) -> FundsByFunderDto.builder() .funderUserId(fundsByFunder1.getFunderUserId()) .funderAddress(fundsByFunder1.getFunderAddress()) .fndValue(TokenValueDto.sum(fundsByFunder1.getFndValue(), fundsByFunder2.getFndValue())) .otherValue(TokenValueDto.sum(fundsByFunder1.getOtherValue(), fundsByFunder2.getOtherValue())) .build(); } }
private Function<FundsByFunderDto, UserFundsDto> mapToUserFundDto() { return fundsByFunder -> UserFundsDto.builder() .funderUserId(fundsByFunder.getFunderUserId()) .funderAddress(fundsByFunder.getFunderAddress()) .fndFunds(pickIfFund(fundsByFunder.getFndValue())) .otherFunds(pickIfFund(fundsByFunder.getOtherValue())) .fndRefunds(pickIfRefund(fundsByFunder.getFndValue())) .otherRefunds(pickIfRefund(fundsByFunder.getOtherValue())) .build(); }
private UserFundsDto buildUserFundsDtoFrom(final FundsByFunderDto funds, final FundsByFunderDto refunds) { return UserFundsDto.builder() .funderUserId(funds.getFunderUserId()) .funderAddress(funds.getFunderAddress()) .fndFunds(funds.getFndValue()) .otherFunds(funds.getOtherValue()) .fndRefunds(refunds.getFndValue()) .otherRefunds(refunds.getOtherValue()) .build(); } }