简体   繁体   中英

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.

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 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);

I think that code could be less clear with using lambdas. Maybe plain old if is better that modern lambda ?

    int sizeSubList = 30;

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM