I have this stream where I get the "daily return" of each balance in the stream, but I want to get the product of all daily returns for each accountId. I know I need to put something like:
.collect(Collectors.groupingBy(n -> n.getAccountId(), Collectors.reducing(BigDecimal.ZERO, BigDecimal::multiply)));
in, but I'm not sure how. Here is the stream so far:
Map<Long, Double> solution = new HashMap<Long, Double>();
balances.stream()
.forEach(n -> {
if(n.getCashflow().compareTo(BigDecimal.ZERO) > 0) {
solution.put(n.getAccountId(), n.getEndingBalance().divide((n.getStartingBalance().add(n.getCashflow())), 6, RoundingMode.FLOOR).doubleValue());
}
else {
solution.put(n.getAccountId(), (n.getEndingBalance().subtract(n.getCashflow())).divide(n.getStartingBalance(), 6, RoundingMode.FLOOR).doubleValue());
}
});
Please feel free to suggest any way to get to this solution, and thank you!
To make it easier to follow, let's separate the computation of daily return from the stream:
Function<Balance, BigDecimal> dailyReturn = n -> {
if (...) {
return ...;
} else {
return ...;
}
}; // or use a ternary statement
Now we can collect a product of all daily returns for each account using the 3-argument toMap
collector:
balances.stream().collect(Collectors.toMap(
Balance::getAccountId,
dailyReturn,
BigDecimal::multiply
));