将多个字段连接成一个字符串,然后使用 collection 对其进行分组以查找每组的总和

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

假设我有以下字段:

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

我想用一个 String 将它们分组,这是 name1、name2 和 name3 的串联。

例如:

name1 = hi
name2 = am
name3 = sarah

String newString = hiamsarah

然后,在我设法通过链式 String 对 objects 进行分组后,我想获得每个组的 amount 字段的总和。

这可能吗?

我已经尝试了所有可能的方法,但就是无法通过。另外,我是 collections.

的新手

假设您的实例包含在 List 中并且在您的 class 中有一种方法可以 return 链接的名称,您可以使用集合流和分组依据您使用终端操作的实例 collect(Collectors.toMap()).

链接的值可以用作键,BigDecimal值作为键对应的值,最后可以通过对BigDecimal值求和来处理冲突情况。

由于您没有提供您所指的 class 的代码,我声明了一个名为 MyClass 的 class 包含 3 个 String 字段和BigDecimal。这是代码片段:

public class Main {
    public static void main(String[] args) {
        List<MyClass> list = new ArrayList<>(List.of(
                new MyClass("I", "am", "Sarah", BigDecimal.valueOf(5.33)),
                new MyClass("I", "am", "Frank", BigDecimal.valueOf(2.75)),
                new MyClass("I", "am", "Sarah", BigDecimal.valueOf(3.56)),
                new MyClass("I", "am", "Frank", BigDecimal.valueOf(7.12)),
                new MyClass("I", "am", "John", BigDecimal.valueOf(1.11))
        ));

        Map<String, BigDecimal> mapRes = list.stream()
                .collect(Collectors.toMap(mc -> mc.chainNames(), mc -> mc.getAmount(), (decimal1, decimal2) -> decimal1.add(decimal2)));

        System.out.println(mapRes);
    }
}

测试class实施(MyClass):

class MyClass {
    private String name1;
    private String name2;
    private String name3;
    private BigDecimal amount;

    public MyClass(String name1, String name2, String name3, BigDecimal amount) {
        this.name1 = name1;
        this.name2 = name2;
        this.name3 = name3;
        this.amount = amount;
    }

    /* ... your implementation ...*/

    public BigDecimal getAmount() {
        return amount;
    }

    public String chainNames() {
        StringBuilder strBld = new StringBuilder(name1);
        strBld.append(name2);
        strBld.append(name3);
        return strBld.toString();
    }
}

这里还有一个link测试代码:

https://ideone.com/IL1ZQ8

  1. 连接多个字符串,有方法String::join,第一个参数是分隔符,可以是空字符串String.join("", name1, name2, name3)
  2. 要按列表中的某些值分组并汇总某个值,Stream API 应与 Collectors.groupingBy + Collectors.reducing
  3. 一起使用

假设给定的 class 实现为自 Java 14 以来提供的 record,则提供以下实现:

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);
}

输出:

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