web-dev-qa-db-fra.com

Sous-listes Java8 d'une liste <> utilisant des lambdas

J'ai un problème qui, à mon avis, conviendrait parfaitement pour les ruisseaux et/ou les lambdas. D’autre part, je ne veux pas trop compliquer les choses, mais comme je vais utiliser cette technique spécifique dans de nombreuses variantes (fonction run sur une sous-liste), je voudrais quelques idées sur la façon de bien faire les choses dès le début.

J'ai un List<Product> productList.

Je veux pouvoir parcourir toutes les sous-listes dans productList. Par exemple, toutes les sous-listes de taille = 30. Cette sous-liste devrait alors être utilisée comme argument d'une fonction.

Voici ma solution actuelle et naïve:

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

Comment cela serait-il implémenté avec lambdas?

EDIT J'ai essayé de donner l'exemple le plus simple possible pour illustrer le problème. Après quelques commentaires, j'ai réalisé qu'un exemple parfait consiste à calculer une moyenne mobile. La première MAVG est calculée sur la sous-liste [0..29], la deuxième sur [1..30], la troisième sur [2..31], etc.

7
Peter Andersson

À moins que je manque quelque chose d'évident ...

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

Eh bien, si vous voulez exécuter plus d'une fonction à ces sous-listes, comme:

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

vous êtes probablement en train de rester avec la boucle habituelle.

une opération map effectue une seule action sur une sous-liste; elle pourrait en faire plus dans un flux, mais cela aura l'air vraiment moche OMI.

6
Eugene

Si cela ne vous dérange pas d'utiliser des bibliothèques tierces, il existe une méthode subLists dans StreamEx qui fait exactement ce que vous voulez:

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

Je pense que ce code pourrait être moins clair avec l'utilisation de lambdas. Peut-être que tout simplement vieux si est mieux que moderne lambda ?

    int sizeSubList = 30;

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