wake-up-neo.com

Java8-Unterlisten einer Liste <> mit Lambdas

Ich habe ein Problem, das meiner Meinung nach perfekt für Streams und/oder Lambdas ist. Andererseits möchte ich das nicht übermäßig komplizieren, aber da ich diese spezielle Technik in vielen Variationen verwenden werde (Funktion auf einer Unterliste ausführen), hätte ich gerne einige Ideen, wie ich es von Anfang an richtig machen kann.

Ich habe einen List<Product> productList.

Ich möchte alle Unterlisten in productList durchlaufen können. Zum Beispiel alle Unterlisten mit Größe = 30. Diese Unterliste sollte dann als Argument für eine Funktion verwendet werden.

Dies ist meine aktuelle, naive Lösung:

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

Wie würde dies mit Lambdas umgesetzt?

EDIT Ich habe versucht, ein möglichst einfaches Beispiel zu finden, um das Problem zu veranschaulichen. Nach einigen Kommentaren wurde mir klar, dass ein perfektes Beispiel die Berechnung eines gleitenden Durchschnitts ist. Das erste MAVG wird anhand der Unterliste [0..29], das zweite anhand der Unterliste [1..30], das dritte anhand der Liste [2..31] usw. berechnet.

7
Peter Andersson

Es sei denn, mir fehlt etwas offensichtliches ...

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

Wenn Sie mehr als nur eine Funktion für diese Unterlisten ausführen möchten, wie:

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

sie sind wahrscheinlich nicht bei der üblichen for-Schleife.

eine map -Operation führt eine einzelne Aktion in einer Unterliste durch. Es könnte jedoch mehr gemacht werden, um einen Stream auszuführen, aber das sieht wirklich hässlich aus.

6
Eugene

Wenn es Ihnen nichts ausmacht, Bibliotheken von Drittanbietern zu verwenden, gibt es in StreamEx eine Methode subLists, die genau das macht, was Sie wollen:

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

Ich denke, dass der Code mit Lambdas weniger klar sein könnte. Vielleicht einfach alt wenn ist das moderne lambda besser?

    int sizeSubList = 30;

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