Java 8 lambdas nested Map -
i trying use java-8 lambdas solve following problem:
given list<transaction>
, each category.minorcategory
require sum of transaction.amount
per category.minorcategory
, map
of transaction.accountnumber
sum of transaction.amount
per transaction.accountnumber
. have working, per code below. have requirement group category.majorcategory
, returning map<string, map<string, minorcategorysummary>>
keyed on category.majorcategory
.
i have working until stage of grouping category.majorcategory
struggle see solution; paradigm shift of programming lambdas proving steep learning curve.
transactionbreakdown
action happens , i'd return map<string, map<string, minorcategorysummary>>
.
public class transaction { private final string accountnumber; private final bigdecimal amount; private final category category; } public class category { private final string majorcategory; private final string minorcategory; } public class minorcategorysummary { private final bigdecimal sumofamountperminorcategory; private final map<string, bigdecimal> accountnumbersumofamountmap; private final category category; } public class transactionbreakdown { function<entry<string, list<transaction>>, minorcategorysummary> transactionsummariser = new transactionsummariser(); public map<object, minorcategorysummary> gettransactionsummaries(list<transaction> transactions) { return transactions .stream() .collect(groupingby(t -> t.getcategory().getminorcategory())) .entryset() .stream() .collect( tomap(entry::getkey, transactionsummariser)); } } public class transactionsummariser implements function<entry<string, list<transaction>>, minorcategorysummary> { @override public minorcategorysummary apply( entry<string, list<transaction>> entry) { return new minorcategorysummary( entry.getvalue() .stream() .map(transaction::getamount) .collect(reducing(bigdecimal.zero, bigdecimal::add)), entry.getvalue() .stream() .collect( groupingby(transaction::getaccountnumber, mapping(transaction::getamount, reducing(bigdecimal.zero, bigdecimal::add)))), entry.getvalue().get(0).getcategory()); } }
your class design seems odd me. why put category summary class have category map key? make more sense have summary class without category in it:
public class transactionsummary { private final bigdecimal amount; private final map<string, bigdecimal> accttototal; transactionsummary(map<string, bigdecimal> accttototal) { this.accttototal = collections.unmodifiablemap(accttototal); this.amount = accttototal.values().stream() .reduce(bigdecimal.zero, bigdecimal::add); } public static collector<transaction, ?, transactionsummary> collector() { // can static constant return collectingandthen( tomap(transaction::getaccountnumber,transaction::getamount,bigdecimal::add), transactionsummary::new ); } // getters }
now 2 problems solved , no redundancy:
map<string, transactionsummary> minorsummary = transactions.stream() .collect(groupingby( t -> t.getcategory().getminorcategory(), transactionsummary.collector() )); map<string, map<string, transactionsummary>> majorminorsummary = transactions.stream() .collect(groupingby( t -> t.getcategory().getmajorcategory(), groupingby( t -> t.getcategory().getminorcategory(), transactionsummary.collector() ) ));
Comments
Post a Comment