Как объединить два List таким образом, чтобы
Как объединить, чтобы одинаковые элементы слились в один и получил на выходе
[productUuid=55d7cd69-7db0-43fc-8bc6-813db36f69f4, productName=Product740, amount=57],
[productUuid=e6296ab4-9f94-4105-8212-b61555a04bef, productName=Product1065, amount=1],
[productUuid=e6296ab4-9f94-4105-8212-b61555a04bef, productName=Product560, amount=2]
первый List состоит из элементов:
[productUuid=55d7cd69-7db0-43fc-8bc6-813db36f69f4, productName=Product740, amount=47],
[productUuid=e6296ab4-9f94-4105-8212-b61555a04bef, productName=Product1065, amount=1]
второй List состоит из элементов:
[productUuid=55d7cd69-7db0-43fc-8bc6-813db36f69f4, productName=Product740, amount=10],
[productUuid=e6296ab4-9f94-4105-8212-b61555a04bef, productName=Product560, amount=2]
Ответы (2 шт):
Автор решения: Alex Rudenko
→ Ссылка
- Группировка по UUID и названию продукта
- Суммирование по полю
amount.
При условии, что существует список продуктов List<Product>, а класс Product имеет соответствующие геттеры для своих полей, указанный алгоритм удобно реализовать при помощи Stream API и коллектора toMap с функцией слияния:
List<Product> summaryByIdName = new ArrayList<>(
Stream.concat(list1.stream(), list2.stream())
.collect(Collectors.toMap(
p -> p.getProductUuid() + "|" + p.getProductName(), // ключ по двум полям
p -> p, // копируем текущее элемент Product
(p1, p2) -> { // слияние при совпадении ключей
p1.setAmount(p1.getAmount() + p2.getAmount()); // суммировать amount
return p1;
},
LinkedHashMap::new // сохранить порядок вставки
)) // Map<String, Product>
.values() // Collection<Product>
);
Автор решения: Aleksandr Kuzminchuk
→ Ссылка
public static List<Goods> merged(List<Goods> fromFile, List<Goods> fromWeb) {
List<Goods> raw = new ArrayList<>();
raw.addAll(fromFile);
raw.addAll(fromWeb);
Map<String, Goods> toReturn = new HashMap<>();
raw.forEach(rawProduct -> {
if (toReturn.get(rawProduct.getProductUuid()) == null) {
toReturn.put(rawProduct.getProductUuid(), rawProduct);
}else {
Goods toChange = toReturn.get(rawProduct.getProductUuid());
int newAmount = toChange.getAmount() + rawProduct.getAmount();
toReturn.get(rawProduct.getProductUuid()).setAmount(newAmount);
}
});
return new ArrayList<>(toReturn.values());
}