Java流API-还原过程中的复杂计算
是否有一些更好的方法在减少方面进行更复杂的计算(检查getCurrentbalance):
@Override
public Map<User, BigDecimal> getTotalExpensesForUsers(Group group) {
return group.getExpenses().stream()
.collect(Collectors.groupingBy(
Expense::getUser,
Collectors.reducing(BigDecimal.ZERO, Expense::getAmount, BigDecimal::add)
));
}
@Override
public Map<User, BigDecimal> getCurrentBalance(Group group) {
final var defaultTotalWeight = BigDecimal.valueOf(group.getDefaultTotalWeight());
var totalExpensesPerUser = getTotalExpensesForUsers(group);
final var averageExpensePerUser = totalExpensesPerUser.values().stream()
.reduce(BigDecimal.ZERO, BigDecimal::add)
.divide(defaultTotalWeight);
totalExpensesPerUser.entrySet()
.forEach(e -> e.setValue(e.getValue().subtract(averageExpensePerUser)));
return totalExpensesPerUser;
}
我想以某种方式将其放入一个流,因为目前我正在多次迭代集合。还是我应该使用循环的情况?
的含义
PS希望是代码自我解释 因为我得到了很多回答,即在一次迭代中不可能做到这一点,所以我正在更新这个问题。我知道不可能在一次迭代中进行操作,但是像这样,我可以用两个迭代来进行:
@Override
public Map<User, BigDecimal> getCurrentBalanceAlternative(Group group) {
var currentBalance = new HashMap<User, BigDecimal>();
final var defaultTotalWeight = BigDecimal.valueOf(group.getDefaultTotalWeight());
var totalExpense = BigDecimal.ZERO;
for(Expense expense: group.getExpenses()){
var expenseUser = expense.getUser();
var expenseAmount = expense.getAmount();
totalExpense = totalExpense.add(expenseAmount);
currentBalance.put(expenseUser, currentBalance.getOrDefault(expenseUser, BigDecimal.ZERO).add(expenseAmount));
}
var averageExpensePerUser = totalExpense.divide(defaultTotalWeight);
currentBalance.entrySet()
.forEach(e -> e.setValue(e.getValue().subtract(averageExpensePerUser)));
return currentBalance;
}
但是,使用流,我必须分别计算totalexpense。
is there some me better way how to do more complicated calculation in reduction than this (check getCurrentBalance):
@Override
public Map<User, BigDecimal> getTotalExpensesForUsers(Group group) {
return group.getExpenses().stream()
.collect(Collectors.groupingBy(
Expense::getUser,
Collectors.reducing(BigDecimal.ZERO, Expense::getAmount, BigDecimal::add)
));
}
@Override
public Map<User, BigDecimal> getCurrentBalance(Group group) {
final var defaultTotalWeight = BigDecimal.valueOf(group.getDefaultTotalWeight());
var totalExpensesPerUser = getTotalExpensesForUsers(group);
final var averageExpensePerUser = totalExpensesPerUser.values().stream()
.reduce(BigDecimal.ZERO, BigDecimal::add)
.divide(defaultTotalWeight);
totalExpensesPerUser.entrySet()
.forEach(e -> e.setValue(e.getValue().subtract(averageExpensePerUser)));
return totalExpensesPerUser;
}
I would like to somehow put it to one stream because currently I am iterating over the collection multiple times. Or is this case when I should use for loop instead?
P.S. hopefully is the meaning of the code self explaining if not, I will update the question
EDITED
Because I got a lot of responses that it is not possible to do it in one iteration I am updating this question. I know it is not possible to do it in one iteration, but like this I am able to do it with two:
@Override
public Map<User, BigDecimal> getCurrentBalanceAlternative(Group group) {
var currentBalance = new HashMap<User, BigDecimal>();
final var defaultTotalWeight = BigDecimal.valueOf(group.getDefaultTotalWeight());
var totalExpense = BigDecimal.ZERO;
for(Expense expense: group.getExpenses()){
var expenseUser = expense.getUser();
var expenseAmount = expense.getAmount();
totalExpense = totalExpense.add(expenseAmount);
currentBalance.put(expenseUser, currentBalance.getOrDefault(expenseUser, BigDecimal.ZERO).add(expenseAmount));
}
var averageExpensePerUser = totalExpense.divide(defaultTotalWeight);
currentBalance.entrySet()
.forEach(e -> e.setValue(e.getValue().subtract(averageExpensePerUser)));
return currentBalance;
}
but with streams I had to calculate the totalExpense separately.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论