如何在单个流中对对象列表进行分组,计数和求和并存储在另一个对象列表中?

use*_*643 5 java collections java-8 java-stream

我试图使用java流和集合从对象列表中获取分组,计数和求和。我不确定如何达到期望的结果。

输入模型

String month;
BigDecimal salary;
String department;
String noOfEmp;
Run Code Online (Sandbox Code Playgroud)

InputModel [(May,100,IT,10),(June,300,IT,7),(July,300,IT,7),(May,1000,HR,5),(June,300,HR,7 ),(7月600,HR,5)]

输出模型

String month
BigDecimal salary
String noOfEmp
Run Code Online (Sandbox Code Playgroud)

预期输出 OutputModel [(May,1100,15),(June,600,14),(July,900,12)]

我尝试了下面的代码,但它返回了group by和Count。

Map<String, Integer> result= inputModels.parallelStream().collect(Collectors.groupingBy(InputModel::getMonth,
            LinkedHashMap::new, Collectors.summingInt(InputModel::getNoOfEmp)));
Run Code Online (Sandbox Code Playgroud)

提前致谢!!!

Rav*_*ala 6

鉴于您已经OutputModel上课,这将解决您的问题。

Collection<OutputModel> outputModels = inputModel.stream()
    .map(im -> new OutputModel(im.getMonth(), im.getSalary(), im.getNoOfEmp()))
    .collect(Collectors.toMap(OutputModel::getMonth, Function.identity(),
        (m1, m2) -> new OutputModel(m1.getMonth(), m1.getSalary().add(m2.getSalary()),
            String.valueOf(Integer.valueOf(m1.getNoOfEmp()) + Integer.valueOf(m2.getNoOfEmp()))),
        LinkedHashMap::new))
    .values();
Run Code Online (Sandbox Code Playgroud)

警告:最好不要在其他类型更合适的地方使用字符串。对于一个实例,你应该用int代表noOfEmp代替String。这将简化代码,同时减少由于虚假数据导致的运行时错误的可能性。此外,考虑使用java.time.Monthenum来表示一年中的月份,而不是使用String文字。

这是输出

[{month =五月,薪水= 1100,noOfEmp = 15},{month =六月,薪水= 600,noOfEmp = 14},{month =七月,薪水= 900,noOfEmp = 12}]

  • 我可以使用,LinkedHashMap :: new使它与月度订单一起使用。谢谢 (2认同)
  • 如果需要保留相遇顺序,则必须将LinkedHashMap :: new传递给mapFactory。我已经相应地更新了答案。 (2认同)