Is flatMap a guarantee of laziness?

Consider the following code:

urls.stream()
    .flatMap(url -> fetchDataFromInternet(url).stream())
    .filter(...)
    .findFirst()
    .get();

Will it be called fetchDataFromInternetfor the second URL if the first is enough?

I tried with a smaller example, and it looks like it works as expected. ie processes data one by one, but can you rely on it? If not, does the call .sequential()to .flatMap(...)?

    Stream.of("one", "two", "three")
            .flatMap(num -> {
                System.out.println("Processing " + num);
                // return FetchFromInternetForNum(num).data().stream();
                return Stream.of(num);
            })
            .peek(num -> System.out.println("Peek before filter: "+ num))
            .filter(num -> num.length() > 0)
            .peek(num -> System.out.println("Peek after filter: "+ num))
            .forEach(num -> {
                System.out.println("Done " + num);
            });

Conclusion:

Processing one
Peek before filter: one
Peek after filter: one
Done one
Processing two
Peek before filter: two
Peek after filter: two
Done two
Processing three
Peek before filter: three
Peek after filter: three
Done three

Update : using official Oracle JDK8, if that matters during implementation

Answer : Based on the comments and answers below, the tablet is partially lazy. I read the first stream completely and only when necessary, it goes further. Reading a thread is impatient, but reading multiple threads is lazy.

, API Iterable .

:

+9
3

flatmap flatmap; ( sorted distinct). :

 int result = Stream.of(1)
            .flatMap(x -> Stream.generate(() -> ThreadLocalRandom.current().nextInt()))
            .findFirst()
            .get();

    System.out.println(result);

, flatMap . :

urls.stream()
    .flatMap(url -> fetchDataFromInternet(url).stream())
    .filter(...)
    .findFirst()
    .get();

, url - flatMap , , . , , url fetchDataFromInternet(url) 10_000 , findFirst 10_000, .

Java 10, : . JDK-8075939

2

Java 8 (8u222): JDK-8225328

+11

, , , . , , , findFirst(), , findFirst() forEach, . , , :

Stream.of("hello", "world")
      .flatMap(s -> {
          System.out.println("flatMap function evaluated for \""+s+'"');
          return s.chars().boxed();
      })
      .peek(c -> System.out.printf("processing element %c%n", c))
      .filter(c -> c>'h')
      .findFirst()
      .ifPresent(c -> System.out.printf("found an %c%n", c));
flatMap function evaluated for "hello"
processing element h
processing element e
processing element l
processing element l
processing element o
found an l

, , flatMap, , , () , Q & A, .

, fetchDataFromInternet, , flatMap, . .

+5

. , , , , .

 stream(spliterator).map(o -> o).flatMap(Stream::of)..flatMap(Stream::of).findAny()

, JDK-10, . . JavaScript, , .

StreamHelper , Spliterator .

https://github.com/yaitskov/j4ts/blob/stream/src/main/java/javaemul/internal/stream/StreamHelper.java

+1

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


All Articles