Java 8 stream - merge collections of objects sharing the same Id

后端 未结 6 1672
后悔当初
后悔当初 2021-02-13 15:11

I have a collection of invoices :

class Invoice {
  int month;
  BigDecimal amount
}

I\'d like to merge these invoices, so I get one invoice pe

6条回答
  •  灰色年华
    2021-02-13 16:10

    If you could add the following copy constructor and merge method to your Invoice class:

    public Invoice(Invoice another) {
        this.month = another.month;
        this.amount = another.amount;
    }
    
    public Invoice merge(Invoice another) {
        amount = amount.add(another.amount); // BigDecimal is immutable
        return this;
    }
    

    You could reduce as you want, as follows:

    Collection result = list.stream()
        .collect(Collectors.toMap(
            Invoice::getMonth, // use month as key
            Invoice::new,      // use copy constructor => don't mutate original invoices
            Invoice::merge))   // merge invoices with same month
        .values();
    

    I'm using Collectors.toMap to do the job, which has three arguments: a function that maps elements of the stream to keys, a function that maps elements of the stream to values and a merge function that is used to combine values when there are collisions on the keys.

提交回复
热议问题