Nested loops, part 2

Jose jgetino at telefonica.net
Tue Apr 9 07:15:43 PDT 2013


Hi,
 
I found some blocks of my code that not just consumes a nested loop, but use
it to genereate a Stream<R>. 

Now I have replaced these blocks with a nested IntStream and a function:

                              int x int -----> R


However I only devised a poorman solution, that consist on storing the
values returned by the function in a collection and generating a Stream<R>
from them.
I revised the IntStream API,  and tried with flatMap(FlatMapper.OfIntToInt
mapper), mapToObj(IntFunction<U> mapper) and some others.
But in the best cases I ended with a Stream<Stream<R>> and had no way to get
it flatten. So I wonder if there is a better solution than mine. 

I've also included a utility class Range2D to make it easier to test nested
loops.


import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.Streams;

@FunctionalInterface
interface IntBiFunction<R> {

    R apply(int x, int y);

    default public Stream<R> nest(IntStream sx, Supplier<IntStream> ssy) {
        List<R> list = new ArrayList<>();
        IntBiConsumer bc = (x, y) -> list.add(apply(x, y));
        bc.nest(sx, ssy);
        return list.stream();
    }

}
@FunctionalInterface
interface IntBiConsumer {

    void accept(int n, int m);
    default public void nest(IntStream sx, Supplier<IntStream> ssy) {
        sx.forEach(nx -> ssy.get().forEach(ny -> accept(nx, ny)));
    }

}
class Range2D {
    int xMin, xMax, yMin, yMax;

    //xMax, yMax will not be reached
    public void forEach(IntBiConsumer biConsumer) {
        IntStream sx = Streams.intRange(xMin, (int) xMax);
        Supplier<IntStream> ssy = () -> Streams.intRange(yMin, yMax);
        biConsumer.nest(sx, ssy);
    }
    public <R> Stream<R> map(IntBiFunction<R> biFunction) {
        IntStream sx = Streams.intRange(xMin, xMax);
        Supplier<IntStream> ssy = () -> Streams.intRange(yMin, yMax);
        return biFunction.nest(sx, ssy);
    }
    public Range2D(int xMin,  int yMin, int xMax,int yMax) {
        this.xMin = xMin;
        this.yMin = yMin;
        this.xMax = xMax;
        this.yMax = yMax;
    }
    public static void main(String[] args) {
        Range2D range2D=new Range2D(0,0,3,4);
        System.out.println("------ FOR EACH ----------");
        range2D.forEach((x,y)->System.out.println("x: " + x + ", y: " + y));
        System.out.println("------ MAP ----------");
        range2D.map((x,y)->"x: " + x + ", y: " +
y).forEach(System.out::println);
    }
}








More information about the lambda-dev mailing list