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.
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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With