Search code examples
javacollectionsstreamjava-streampojo

Java. Group and sum exact values in collection of Java Objects


Aaaah, it's finally happened, and I asking for help :(

Let's start: I have a list of incoming transactions, for example:

List<FinancialTransaction> incomingTransactions = new ArrayList();
incomingTransactions.add(new FinancialTransaction(1, 1, 2, 1000000));
incomingTransactions.add(new FinancialTransaction(2, 1, 2, 2000000));
incomingTransactions.add(new FinancialTransaction(3, 2, 1, 1000000));
incomingTransactions.add(new FinancialTransaction(4, 2, 1, 4000000));
incomingTransactions.add(new FinancialTransaction(5, 2, 3, 1000000));

FinancialTransaction POJO:

public class FinancialTransaction {

    private Integer id;

    private Integer srcId;

    private Integer dstId;

    private Long amount;

    public Integer getId() {
        return id;
    }

    //getters, setters, constructors, toString
}

Then incomingTransactions moves to method listed below, which must create a new Map, with a key of srcId and dstId of FinancialTransaction, group by this key, sum "amount" value of grouped objects, and put new object with Id = sdcId and dstId, srcId = this.srcId, dstId = this.dstId, and amount = sum of all grouped objects:

public class TransactionMerger {


    public static Map<String, FinancialTransaction> mergeTransactions(List<FinancialTransaction> financialTransactions) {

        Map<String, FinancialTransaction> mergedTransactions = new HashMap<>();

        for (FinancialTransaction ft: financialTransactions) {

            String key = ft.getSrcId() + "" + ft.getDstId();

            if (mergedTransactions.get(key) != null) {
                mergedTransactions.put(key, ft);
            } else {
//          Don't know to write here :/
            }

        }

        financialTransactions.clear();

        return mergedTransactions;
    }

}

This method must absorb incomingTransactions return something like:

Key: 12 Value: FinancialTransaction {12, 1, 2, 3000000} //summed first and second values in incoming list
Key: 21 Value: FinancialTransaction {21, 2, 1, 5000000} //summed third and fourth values in incoming list
Key: 23 Value: FinancialTransaction {23, 2, 3, 1000000} //returned fifth values

Please help I have no Ideas, I already know how to group with composite key, from several values, but ho to sum and group - have no ideas please help!!!!!

Big thx guys!!!


Solution

  • public static Map<String, FinancialTransaction> mergeTransactions(List<FinancialTransaction> financialTransactions) {
    
            Map<String, FinancialTransaction> mergedTransactions = new HashMap<>();
    
            for (FinancialTransaction ft: financialTransactions) {
    
                String key = ft.getSrcId() + "" + ft.getDstId();
    
                if (mergedTransactions.containsKey(key)) {
                    //get the existing FinancialTransaction for the key and updates it's amount only
                    mergedTransactions.get(key).setAmount(mergedTransactions.get(key).getAmount() + ft.getAmount());
                } else {
                    //create new FinancialTransaction object for the map
                    FinancialTransaction financialTransaction = new FinancialTransaction();
                    //do not set Id for the new object, as its not db generated, key will behave like id
                    financialTransaction.setSrcId(ft.getSrcId());
                    financialTransaction.setDstId(ft.getDstId());
                    financialTransaction.setAmount(ft.getAmount());
                    mergedTransactions.put(key, financialTransaction);
                }
            }
    
            financialTransactions.clear();
            return mergedTransactions;
        }
    

    Hope this helps. I have added comments let me know if you need more clarity.