假设txn流,其中每个txn具有以下字段
{date,amt,name,merchant}
给出txn流
按yyyy-mm //折叠1
在组内(yyyy-mm);映射到新对象费用(收入,支出)
如果金额> 0然后收入+ = amt //条件折叠2.a
如果金额< 0然后花费+ = amt //条件折叠2.b
我想知道在java中实现上述方法是什么。 尝试下面,它很短暂
txns
.stream()
.collect(
Collectors.groupingBy(
Txn::getYearMonth,
Collectors.mapping(
getExpense,
Collectors.toList())));
getexpense是我编写的函数映射,用于将Txn转换为Expense对象。
答案 0 :(得分:0)
我认为你被困在了一步。您发布的代码将导致:
Map<YearMonth, List<Expense>>
虽然我猜你想要:
Map<YearMonth, Expense> // transactions aggregated into a single Expense
为此,您需要创建一个可以聚合Expense
个对象的收集器。
看起来像这样:
Collector.of(
Expense::new,
(Expense e, Transaction t) -> e.add(t),
(e1, e2) -> new Expense(e1, e2)
);
您的费用等级需要:
add
添加到Transaction
Expense
方法
醇>
这样的事情:
public class Expense {
private double income;
private double spent;
public Expense() {
}
public Expense(Expense e1, Expense e2) {
this.income = e1.income + e2.income;
this.spent = e1.spent + e2.spent;
}
public void add(Transaction t) {
this.income += t.getAmount() > 0 ? t.getAmount() : 0;
this.spent += t.getAmount() < 0 ? t.getAmount() : 0;
}
}
然后,您可以在groupingBy中使用此Collector
:
groupingBy(Txn::getYearMonth, myCollector)
结果将是单个Expense
对象中的汇总费用。
<强>更新强>
所以这样:
Collector<Transaction, Expense, Expense> c = Collector.of(
Expense::new,
(Expense e, Transaction t) -> e.add(t),
(e1, e2) -> new Expense(e1, e2)
);
Map<YearMonth, Expense> collect = txns.stream()
.collect(Collectors.groupingBy(Transaction::getYearMonth, c));