Как отображать и суммировать элементы из списка в Java
Источник:
DZone
В этой публикации вы узнаете, как из списка в Java отобразить и суммировать количество элементов. Отображение элементов из списка (
List) означает, что каждый элемент из этого списка будет преобразован в другой объект. Суммирование элементов из списка означает, что все элементы из этого списка будут объединены в один объект, который не обязательно имеет тот же тип, что и исходный.
Допустим, у нас есть список заказов, и в каждом заказе есть список продуктов.
record Order(String customer, List<Product> products) {
}
record Product(String brand, String modelName, BigDecimal price) {
}
Что бы вы сделали, если бы требовалось узнать, сколько денег поступает из списка заказов?
Для каждого заказа вам нужно будет получить список присутствующих в нем продуктов, а для каждого продукта в этих списках нужно получить его стоимость. После этого вам требуется суммировать все эти цены, и так вы получите результат.
При переводе приведенного выше на
Map /
Reduce вам необходимо:
- Сопоставить каждый заказ со списком продуктов.
- Отобразить для каждого продукта его цену.
- Суммировать все цены, сложив их друг с другом.
Итак, сделаем это на Java:
public class OrderMapReducer {
public BigDecimal getTotal(List<Order> orders) {
return orders.stream() // 1
.map(Order::products) // 2
.flatMap(List::stream) // 3
.map(Product::price) // 4
.reduce(BigDecimal::add) // 5
.orElse(BigDecimal.ZERO); // 6
}
}
- Создаем поток заказов.
- Сопоставляем каждый заказ с его списком продуктов.
- Сопоставляем каждый список продуктов с потоком. Обратите внимание, что здесь нам пришлось использовать flatMap, иначе мы получим Stream <Stream <Product>>.
- Отображаем для каждого продукта его цену.
- Суммируем все цены.
- Если список заказов (Order List) пуст, возвращаем zero.
Вот и все! Теперь мы можем создать тест, чтобы убедиться, что все работает должным образом.
@Test
void getTotalPrice() {
List<Order> orders = createOrders();
OrderMapReducer orderMapReducer = new OrderMapReducer();
assertEquals(new BigDecimal(17800), orderMapReducer.getTotal(orders));
}
private static List<Order> createOrders() {
var strato = new Product("Fender", "Stratocaster", new BigDecimal(3500));
var sg = new Product("Gibson", "SG", new BigDecimal(4800));
var lesPaul = new Product("Gibson", "Les Paul", new BigDecimal(4500));
var rr = new Product("Jackson", "RR", new BigDecimal(5000));
return List.of(
new Order("David Gilmour", List.of(strato)),
new Order("Toni Iommi", List.of(sg)),
new Order("Randy Rhoads", List.of(lesPaul, rr))
);
}
Как видите, сопоставление и суммирование (Map and Reduce) помогает в тех случаях, когда вам нужно извлечь информацию из
Collection.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ