Java8 sublists of a List<> using lambdas

15,824

Solution 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.

Solution 2

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

Solution 3

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())));
Share:
15,824

Related videos on Youtube

Peter Andersson
Author by

Peter Andersson

C/C++/Java/C#/Objective-C and lots of other languages are now side-stepped by RUBY ON RAILS, my new favourite. Born in Valbo, Sweden, but an international citizen. Spent five years in Zug,Switzerland and ten years in Stockholm, Sweden. Prefers open source before closed environments.

Updated on June 04, 2022

Comments

  • Peter Andersson
    Peter Andersson almost 2 years

    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.

    • JB Nizet
      JB Nizet about 7 years
      Using streams and lambdas won't make the code more readable, on the contrary.