Попробуйте это
РЕШЕНИЕ 1
Один из способов сделать это -
List<Pricing> allPricings = getAllPricings();
List<Pricing> result = allPricings.stream()
.collect(Collectors.groupingBy(Pricing::getUserCode))
.entrySet().stream()
.map(e -> e.getValue().stream()
.reduce((f1,f2) -> new Pricing(f1.getId(),f1.getPrice() + f2.getPrice(),f1.getUserCode())))
.map(f -> f.get())
.collect(Collectors.toList());
РЕШЕНИЕ 2
Это более компактный способ
Collection<Pricing> result2 =
allPricings.stream()
.collect(groupingBy(Pricing::getUserCode,
collectingAndThen(
reducing((p1, p2)-> new Pricing(p1.getId(),p1.getPrice() + p2.getPrice(),p2.getUserCode())), Optional::get)))
.values();
РЕШЕНИЕ 3
Если вы не хотите создавать объект, попробуйте следующий. Но одним из побочных эффектов этой реализации является то, что она изменяет исходное содержимое списка, поэтому лучше не использовать исходный список, а использовать клонированный.
Collection<Pricing> result3 =
allPricings.stream()
.collect(groupingBy(Pricing::getUserCode,
collectingAndThen(
reducing((p1, p2)-> {
p1.setPrice(p1.getPrice() + p2.getPrice());
return p1;
}), Optional::get)))
.values();
Пример функции для getAllPricings
private static List<Pricing> getAllPricings() {
List<Pricing> pricings = new ArrayList<>();
pricings.add(new Pricing(1, 10.5, "AAA"));
pricings.add(new Pricing(2, 9.5, "AAA"));
pricings.add(new Pricing(3, 10.0, "AAA"));
pricings.add(new Pricing(4, 10.0, "BBB"));
pricings.add(new Pricing(5, 10.0, "BBB"));
return pricings;
}
Результат
[
{
"id": 1,
"price": 30,
"userCode": "AAA"
},
{
"id": 4,
"price": 20,
"userCode": "BBB"
}
]