0

I cant write a collector that calculates the total sum of transactions (long type, not integer) by each account (i.e. by account number). The collector will be applied to a stream of transactions. How to use groupingBy for this chain Transaction -> Account -> Number ?

class TransactionCollector {

public static Map<String, Long> getAccount2TransSum(List<Transaction> trans) {
    return trans.stream().collect(  // place code here 
            }

static class Transaction {

    private final String uuid;
    private final Long sum;
    private final Account account;

    public Transaction(String uuid, Long sum, Account account) {
        this.uuid = uuid;
        this.sum = sum;
        this.account = account;
    }

    public String getUuid() {
        return uuid;
    }

    public Long getSum() {
        return sum;
    }

    public Account getAccount() {
        return account;
    }

    @Override
    public String toString() {
        return "Transaction{" +
                "uuid='" + uuid + '\'' +
                ", sum=" + sum +
                '}';
    }
}

static class Account {
    private final String number;
    private final Long balance;

    public Account(String number, Long balance) {
        this.number = number;
        this.balance = balance;
    }

    public String getNumber() {
        return number;
    }

    public Long getBalance() {
        return balance;
    }

    @Override
    public String toString() {
        return "Account{" +
                "number='" + number + '\'' +
                ", balance=" + balance +
                '}';
    }
}

}

stereouho
  • 45
  • 1
  • 7
  • There have been some recent questions reg. accounts, and also reg. streams. You might find them helpful: https://stackoverflow.com/questions/62102927/throwing-own-exceptions/62103467 , https://stackoverflow.com/questions/62124337/using-java-stream-api-finding-highest-value-of-variable-with-the-stream-of-the/62130292 – MelvinWM Jun 01 '20 at 19:27

2 Answers2

2

You can use a downstream collector

trans.stream().collect(
  groupingBy(
    Transaction::getAccount,
    groupingBy(Account::getNumber)
  )
)

This will first group the transactions by their accounts, and then by their numbers

EDIT: It seems like you actually want the toMap collector

trans.stream().collect(
    toMap(
      t -> t.getAccount().getNumber(),
      t -> t.getSum()
    )
)
user
  • 7,435
  • 3
  • 14
  • 44
  • i dont understand, but .. Compilation error Main.java:11: error: no suitable method found for groupingBy(Transactio[...]count,Collector>>) groupingBy(Transaction::getAccount, groupingBy(Account::getNumber))); – stereouho Jun 01 '20 at 20:04
0

You can use groupingBy with the summingLong collector to group the transactions and calculate their sums.

trans.stream()
    .collect(Collectors.groupingBy(
        transaction -> transaction.getAccount().getNumber(),
        Collectors.summingLong(Transaction::getSum)))

As a result you will have a Map<String, Long> where the key is the account number and the value is the sum of all transactions of accounts with that number.

Tolik Pylypchuk
  • 680
  • 1
  • 6
  • 15