Stream to filter and sum different fields depending on different conditions

Viewed 103

I have a list:

ID | Product Code | Product Type | Transaction Amt | Charges Amt | Charges ID 
1  | 001          | 001          | 10.00           | 0.01        | 001
2  | 001          | 001          | 11.00           | 0.01        | 001
3  | 002          | 001          | 12.00           | 0.01        | 002

I want to have this result:

ID | Product Code | Product Type | Transaction Amt | Charges Amt | Charges ID
1  | 001          | 001          | 21.00           | 0.01        | 001
3  | 002          | 001          | 12.00           | 0.01        | 002

I want to sum up the transaction amount and charges, but when the charges id is same, I will only calculates once.

Below is the code to sum up based on product code and type:

    Map<String, Transaction> map = txs.stream()
        .map(s -> {
            s.setTotalCount(1);
            return s;
        })
        .collect(Collectors.toMap(f -> f.getProductCode() + f.getProductType()
        Function.identity(), 
        (s, a) -> new FeeAllocationTransactionModel(
                s.getProductCode(),
                s.getProductType(),
                s.getTranzAmt().add(a.getTranzAmt()),
                s.getCharges().add(a.getFeeCharges()),
                s.getTotalCount() + 1
        )));
    List<Transaction> reduced = new ArrayList<>(map.values());

From the code above I got:

ID | Product Code | Product Type | Transaction Amt | Charges Amt | Charges ID
1  | 001          | 001          | 21.00           | **0.02**        | 001
3  | 002          | 001          | 12.00           | 0.01        | 002
1 Answers

You could check the charges id in your mergeFunction to Collectors.toMap:

(s, a) -> {
    double charges = (s.getChargesId().equals(a.getChargesId())
        ? s.getCharges()
        : s.getCharges().add(a.getFeeCharges());
    return new FeeAllocationTransactionModel(
                s.getProductCode(),
                s.getProductType(),
                s.getTranzAmt().add(a.getTranzAmt()),
                charges,
                s.getTotalCount() + 1);
}
Related