Considering list elements that are added after filtered stream creation

mmuzahid :

Given the following code:

List<String> strList = new ArrayList<>(Arrays.asList("Java","Python","Php"));

Stream<String> jFilter = strList.stream().filter(str -> str.startsWith("J"));

strList.add("JavaScript"); // element added after filter creation
strList.add("JQuery"); // element added after filter creation

System.out.println(Arrays.toString(jFilter.toArray())); 

which outputs:

[Java, JavaScript, JQuery]

Why do JavaScript and JQuery appear in the filtered result even though they were added after creating the filtered stream?

Ousmane D. :

Short Answer

You're assuming after this point:

Stream<String> jFilter = strStream.filter(str -> str.startsWith("J"));

That a new stream of the elements starting with "J" are returned i.e. only Java. However this is not the case;

streams are lazy i.e. they don't perform any logic unless told otherwise by a terminal operation.

The actual execution of the stream pipeline starts on the toArray() call and since the list was modified before the terminal toArray() operation commenced the result will be [Java, JavaScript, JQuery].

Longer Answer

here's part of the documentation which mentions this:

For well-behaved stream sources, the source can be modified before the terminal operation commences and those modifications will be reflected in the covered elements. For example, consider the following code:

 List<String> l = new ArrayList(Arrays.asList("one", "two"));
 Stream<String> sl = l.stream();
 l.add("three");
 String s = sl.collect(joining(" "));  

First a list is created consisting of two strings: "one"; and "two". Then a stream is created from that list. Next the list is modified by adding a third string: "three". Finally the elements of the stream are collected and joined together. Since the list was modified before the terminal collect operation commenced the result will be a string of "one two three". All the streams returned from JDK collections, and most other JDK classes, are well-behaved in this manner;

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=35376&siteId=1