Replace nested loop on Java 8 tablet

I am trying to use flatmap to create a nested loop with the Stream API, but I cannot figure it out. As an example, I want to recreate the following loop:

List<String> xs = Arrays.asList(new String[]{ "one","two", "three"});
List<String> ys = Arrays.asList(new String[]{"four", "five"});

System.out.println("*** Nested Loop ***");
for (String x : xs)
    for (String y : ys)
        System.out.println(x + " + " + y);

I can do it like this, but it seems ugly:

System.out.println("*** Nested Stream ***");
xs.stream().forEach(x ->
    ys.stream().forEach(y -> System.out.println(x + " + " + y))
);

Flatmap looks promising, but how can I access a variable in an outer loop?

System.out.println("*** Flatmap *** ");
xs.stream().flatMap(x -> ys.stream()).forEach(y -> System.out.println("? + " + y));

Conclusion:

*** Nested Loop ***
one + four
one + five
two + four
two + five
three + four
three + five
*** Nested Stream ***
one + four
one + five
two + four
two + five
three + four
three + five
*** Flatmap *** 
? + four
? + five
? + four
? + five
? + four
? + five
+4
source share
3 answers

You need to create the necessary elements at the stage flatMap, for example:

xs.stream().flatMap(x -> ys.stream().map(y -> x + " + " + y)).forEach(System.out::println);
+7
source

Generally, there is no need for flatMap:

xs.forEach(x -> ys.stream().map(y ->  x + " + " + y).forEach(System.out::println)); // X
xs.forEach(x -> ys.forEach(y -> System.out.println(x + " + " + y))); // V

since there is no need for Stream API.

, , . / , . ?

, forEach - ( forEach ).

+1

, . :

List<String> xs = Arrays.asList(new String[]{ "one","two", "three"});
List<String> ys = Arrays.asList(new String[]{"four", "five"});
List<List<String>> input = Arrays.asList(xs, ys);

, Supplier:

Supplier<Stream<String>> result = input.stream() // Stream<List<String>>
                .<Supplier<Stream<String>>>map(list -> list::stream) // Stream<Supplier<Stream<String>>>

, :

.reduce((sup1, sup2) -> () -> sup1.get().flatMap(e1 -> sup2.get().map(e2 -> e1 + e2)))

Reducing the return is optional, therefore, to process the missing value, I will return an empty stream of strings:

.orElse(() -> Stream.of(""));

In the end, we just need to get the provider value (which will be a stream of lines) and print it:

s.get().forEach(System.out::println);

The whole method will look like this:

public static void printCartesianProduct(List<String>... lists) {
        List<List<String>> input = asList(lists);
        Supplier<Stream<String>> s = input.stream()
                // Stream<List<String>>
                .<Supplier<Stream<String>>>map(list -> list::stream)
                // Stream<Supplier<Stream<String>>>
                .reduce((sup1, sup2) -> () -> sup1.get()
                        .flatMap(e1 -> sup2.get().map(e2 -> e1 + e2)))
                .orElse(() -> Stream.of(""));

        s.get().forEach(System.out::println);
    }
0
source

Source: https://habr.com/ru/post/1661208/


All Articles