Java 流,如何 GROUP BY 并找到流的产品
Java stream, how to GROUP BY and find product of stream
我有这个流,我可以在其中获取流中每个余额的 "daily return",但我想获取每个 accountId 的所有每日 returns 的乘积。我知道我需要输入类似的内容:
.collect(Collectors.groupingBy(n -> n.getAccountId(), Collectors.reducing(BigDecimal.ZERO, BigDecimal::multiply)));
在,但我不确定如何。这是目前的流:
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());
}
});
请随时提出解决此问题的方法,谢谢!
为了更容易理解,让我们将每日 return 的计算与流分开:
Function<Balance, BigDecimal> dailyReturn = n -> {
if (...) {
return ...;
} else {
return ...;
}
}; // or use a ternary statement
现在我们可以使用 3 参数 toMap
收集器为每个帐户收集所有每日 return 的产品:
balances.stream().collect(Collectors.toMap(
Balance::getAccountId,
dailyReturn,
BigDecimal::multiply
));
public class Balance {
private Long accountId;
private BigDecimal cashflow;
private BigDecimal startingBalance;
private BigDecimal endingBalance;
}
List<Balance> balances = new ArrayList<>();
Map<Long, Double> solution2 = balances.stream().map(n -> {
BigDecimal bd;
if (n.getCashflow().compareTo(BigDecimal.ZERO) > 0) {
bd = n.getEndingBalance()
.divide(n.getStartingBalance().add(n.getCashflow()),
6, RoundingMode.FLOOR);
} else {
bd = (n.getEndingBalance().subtract(n.getCashflow()))
.divide(n.getStartingBalance(), 6,
RoundingMode.FLOOR);
}
return new SimpleEntry<Long, Double>(n.getAccountId(), bd.doubleValue());
}).collect(Collectors.groupingBy(Entry::getKey,
Collectors.reducing(1d, Entry::getValue, (d1, d2) -> d1 * d2)));
System.out.println(solution2);
我有这个流,我可以在其中获取流中每个余额的 "daily return",但我想获取每个 accountId 的所有每日 returns 的乘积。我知道我需要输入类似的内容:
.collect(Collectors.groupingBy(n -> n.getAccountId(), Collectors.reducing(BigDecimal.ZERO, BigDecimal::multiply)));
在,但我不确定如何。这是目前的流:
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());
}
});
请随时提出解决此问题的方法,谢谢!
为了更容易理解,让我们将每日 return 的计算与流分开:
Function<Balance, BigDecimal> dailyReturn = n -> {
if (...) {
return ...;
} else {
return ...;
}
}; // or use a ternary statement
现在我们可以使用 3 参数 toMap
收集器为每个帐户收集所有每日 return 的产品:
balances.stream().collect(Collectors.toMap(
Balance::getAccountId,
dailyReturn,
BigDecimal::multiply
));
public class Balance {
private Long accountId;
private BigDecimal cashflow;
private BigDecimal startingBalance;
private BigDecimal endingBalance;
}
List<Balance> balances = new ArrayList<>();
Map<Long, Double> solution2 = balances.stream().map(n -> {
BigDecimal bd;
if (n.getCashflow().compareTo(BigDecimal.ZERO) > 0) {
bd = n.getEndingBalance()
.divide(n.getStartingBalance().add(n.getCashflow()),
6, RoundingMode.FLOOR);
} else {
bd = (n.getEndingBalance().subtract(n.getCashflow()))
.divide(n.getStartingBalance(), 6,
RoundingMode.FLOOR);
}
return new SimpleEntry<Long, Double>(n.getAccountId(), bd.doubleValue());
}).collect(Collectors.groupingBy(Entry::getKey,
Collectors.reducing(1d, Entry::getValue, (d1, d2) -> d1 * d2)));
System.out.println(solution2);