it-swarm.com.ru

Java8 подсписки списка <> с использованием лямбда-выражений

У меня есть проблема, которая, по моему мнению, была бы идеальной для потоков и/или лямбд. С другой стороны, я не хочу чрезмерно усложнять это, но поскольку я буду использовать эту конкретную технику во многих вариантах (функция запуска в подсписке), я хотел бы получить некоторые идеи о том, как сделать это правильно с самого начала.

У меня есть List<Product> productList.

Я хочу иметь возможность перебирать все подсписки в productList. Например, все списки с размером = 30. Этот подсписок следует затем использовать в качестве аргумента функции.

Это мое текущее, наивное решение:

List<Product> products=...
// This example uses sublists of size 30
for (int i = 0; i < products.size() - 29; i++) {
    // sublist start index is inclusive, but end index is exclusive
    List<Product> sublist = products.subList(i, i + 30);
    Double res = calc(sublist);
}

// an example of a function would be moving average

Как это будет реализовано с помощью лямбды?

РЕДАКТИРОВАТЬ Я попытался придумать простейший пример, чтобы проиллюстрировать проблему. После некоторых комментариев я понял, что идеальным примером является вычисление скользящей средней. Первый MAVG рассчитывается для подсписка [0..29], второй для [1..30], третий для [2..31] и так далее. 

7
Peter Andersson

Если я не пропустил что-то очевидное ...

IntStream.range(0, products.size() - 29)
            .mapToObj(i -> products.subList(i, i + 30))
            .map(list -> calc(list))
            .forEach... // or any other terminal op

Хорошо, если вы хотите запустить больше, чем одну функцию для этих подсписков, например:

double result = calc(sublist)
log(sublist) // void
double res = diffCalc(sublist)

вы, вероятно, отстали от обычного цикла.

операция map выполняет одно действие для подсписка, его можно сделать для выполнения большего в потоке, но это будет выглядеть очень уродливо для IMO.

6
Eugene

Если вы не против использования сторонних библиотек, есть метод subLists в StreamEx , который делает именно то, что вы хотите:

List<Product> products = ...
Stream<List<Product>> lists = StreamEx.ofSubLists(products, 30, 1);
4
ZhekaKozlov

Я думаю, что код может быть менее понятным с использованием лямбда-выражений. Может быть, старый добрый если лучше современного лямбда ?

    int sizeSubList = 30;

    for (int i = 0; i < products.size(); i++)
        calc(products.subList(i, Math.min(i + sizeSubList, products.size())));
1
oleg.cherednik