'Concat multiple fields into one string, then group by it using collection to find sum of each group

Imagine I have the following fields:

>  String name1
>  String name2
>  String name3
>  BigDecimal amount

I want to group them by using one String which is the concatenation of name1, name2 and name3.

For example:

name1 = hi
name2 = am
name3 = sarah

String newString = hiamsarah

Then, after I manage to group the objects by the chained String, I want to get the overall sum of the amount field for each group.

Is this possible?

I've tried any possible way, but I just can't get through it. Also, I'm kind of new to collections.



Solution 1:[1]

  1. To concatenate multiple strings, there is method String::join, the first argument is a delimiter which can be an empty string String.join("", name1, name2, name3)
  2. To group by some values in a list and summarize a certain value, Stream API should be used with Collectors.groupingBy + Collectors.reducing

Assuming that the given class is implemented as a record provided since Java 14, the following implementation is offered:

public static void main(String[] args) {
    record MyObj(String name1, String name2, String name3, BigDecimal amount) {
        public String fullName() {
            return String.join("", name1, name2, name3);
        }
    };
    
    List<MyObj> list = List.of(
            new MyObj("I", "am", "Sarah", BigDecimal.valueOf(5.33)),
            new MyObj("I", "am", "Frank", BigDecimal.valueOf(2.75)),
            new MyObj("I", "am", "Sarah", BigDecimal.valueOf(3.56)),
            new MyObj("I", "am", "Frank", BigDecimal.valueOf(7.12)),
            new MyObj("I", "am", "John",  BigDecimal.valueOf(1.11))
    );

    Map<String, BigDecimal> mapRes = list.stream()
            .collect(Collectors.groupingBy(
                MyObj::fullName, 
                Collectors.reducing(BigDecimal.ZERO, MyObj::amount, BigDecimal::add)
            ));

    System.out.println(mapRes);
}

Output:

{IamJohn=1.11, IamSarah=8.89, IamFrank=9.87}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nowhere Man