Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java8 sublists of a List<> using lambdas

I have a problem which I feel would be perfect for streams and/or lambdas. On the other hand I don't want to overcomplicate this, but since will use this specific technique in many variations (run function on a sublist), I would like some ideas about how to get it right from the beginning.

I have a List<Product> productList.

I want to be able to iterate over all sublists in productList. For example all sublists with size=30. This sublist should then be used as an argument to a function.

This is my current, naive, solution:

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

How would this be implemented using lambdas?

EDIT I tried to come up with the simplest possible example to illustrate the problem. After some comments, I realized that a perfect example is calculating a moving average. First MAVG is calculated on sublist [0..29], second on [1..30], third on [2..31] and so on.

like image 822
Peter Andersson Avatar asked Apr 03 '17 19:04

Peter Andersson


2 Answers

If you don't mind using third party libraries, there is a method subLists in StreamEx that does exactly what you want:

List<Product> products = ...
Stream<List<Product>> lists = StreamEx.ofSubLists(products, 30, 1);
like image 196
ZhekaKozlov Avatar answered Oct 02 '22 00:10

ZhekaKozlov


Unless I'm missing something obvious...

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

Well if you want to run more then a single function to these sublists, like:

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

you are probably off staying with the usual for loop.

a map operation does a single action on a sublist, it could be made to do more in a stream, but that will look really ugly IMO.

like image 37
Eugene Avatar answered Oct 02 '22 00:10

Eugene