我有一个对象列表,我需要将其按2个不同的属性进行分组,然后对一个属性的值求和,我的对象的结构如下所示:

private Long id1;
private Long id2;
private Double amountReserved;
private Double amountRequired;
//... more atributes and getters and setters

因此,我有一个列表,例如:
List<MyList> list = Arrays.asList(
list(1, A, 50, 200)
list(1, A, 50, 200)
list(1, B, 0, 100)
list(2, A, 10, 15)
list(2, A, 5, 15)
list(3, A, 0, 25));

我想要实现的是具有以下结构的新列表:
list(1, A, 100, 100)
list(1, B,   0, 100)
list(2, A,  15,   0)
list(3, A,   0,  25)

阐明我要达到的要求是什么:
  • 按id1和id2分组对象
  • 对分组对象
  • amountReserved求和
  • 从求和后的amountRequired中减去amountReserved

  • 到目前为止,我所拥有的:

    这是我想要的分组
    Map<Long, Map<String, List<MyList>>> map = null;
    map = lista.stream().collect(Collectors.groupingBy(PreSeparacaoDto::getCodigoPedido,
                        Collectors.groupingBy(PreSeparacaoDto::getCodigoProduto)));
    

    这个按组id1求和,但是由于出现语法错误,我正在努力在其上添加第二个groupingby:
    lista.stream()
            .collect(Collectors.groupingBy(PreSeparacaoDto::getCodigoPedido,
                    Collectors.summingDouble(PreSeparacaoDto::getProdutoQuantidadeSeparada)))
            .forEach((codigoPedido, ProdutoQuantidadeSeparada) -> System.out.println( codigoPedido + ": " + ProdutoQuantidadeSeparada  ));
    

    我的问题是,我未能按照要求2的要求将它们放在一起,甚至没有接近达到要求3的水平。

    我尝试使用还原,如here所述,但老实说,我无法使用单个分组进行复制,还原是返回错误,通知我的参数不符合reducing参数。我在stackoverflow和其他网站上寻找了其他选择,但没有成功。

    有人可以帮助我并在我无法将减少与我的团队相结合的地方苦恼吗,或者这是否是我应该遵循的正确方法。

    最佳答案

    您可能只是在寻找Collectors.toMap:

    List<MyList> output = new ArrayList<>(lista.stream()
            .collect(Collectors.toMap(a -> a.getId1() + "-" + a.getId2(), a -> a, (myList1, myList2) -> {
                myList1.amountReserved = myList1.amountReserved + myList2.amountReserved;
                myList1.amountRequired = myList1.amountRequired - myList1.amountReserved;
                return myList1;
            })).values());
    

    09-11 20:02
    查看更多