Raikonne
Raikonne

Reputation: 195

Nested for loops to Java 8 Stream API representation

Recently I have decided to look into Java 8 by refactoring simple pieces of code. I have following example which I am trying to convert into Java 8 representation.

public static void halfTriangle(){
        for(int i=1; i<=4; i++){
            for(int j=1; j<=i; j++){
                System.out.print("* ");
            }
            System.out.println(" ");
        }
    }

I have managed to come up with something like this:

public static void halfTriangleJava8(){
        IntStream.range(1, 5)
            .forEach(i -> IntStream.range(1, 5)
                .forEach(j -> System.out.println("* "))
        );
    }

but I have no idea where I could place remaining:

System.out.println(" ");

I have tried something like:

public static void halfTriangleJava8(){
        IntStream.range(1, 5)
            .forEach(i -> {
                IntStream.range(1, 5);
                System.out.println(" ");
            }
                .forEach(j -> System.out.println("* "))
        );
    }

But it gives me an error which I don't fully understand. "The target type for this expression must be a functional interface".

I believe it's a very simple error but I have only started looking into Java 8 today so any help would be greatly appreciated.

Upvotes: 2

Views: 356

Answers (2)

Tunaki
Tunaki

Reputation: 137289

This is not going to be more elegant but you can have:

public static void halfTriangleJava8(){
    IntStream.range(1, 5).forEach(i -> {
        IntStream.rangeClosed(1, i).forEach(j -> System.out.print("* "));
        System.out.println(" ");
    });
}

Althought for those sorts of problems, it'd be better to keep a good-old for loop.

A somewhat prettier way would be to map each integer into the String to be printed at the corresponding line:

public static void halfTriangleJava8(){
    IntStream.range(1, 5)
             .mapToObj(i -> String.join(" ", Collections.nCopies(i, "*")))
             .forEach(System.out::println);
}

Upvotes: 5

Elliott Frisch
Elliott Frisch

Reputation: 201527

You can add {} braces; and you might use IntStream.rangeClosed(int, int) so you can keep the same indices. Something like,

IntStream.rangeClosed(1, 4).forEach(i -> {
    IntStream.rangeClosed(1, i).forEach(j -> System.out.print("* "));
    System.out.println();
});

Upvotes: 1

Related Questions