问题
In java 8, I am using Streams to print the output, but size is coming as 0. Why?
public class IntermediateryAndFinal {
public static void main(String[] args) {
Stream<String> stream = Stream.of("one", "two", "three", "four", "five");
Predicate<String> p1 = Predicate.isEqual("two");
Predicate<String> p2 = Predicate.isEqual("three");
List<String> list = new ArrayList<>();
stream.peek(System.out::println)
.filter(p1.or(p2))
.peek(list::add);
System.out.println("Size = "+list.size());
}
}
回答1:
Ideally you should not mutate an external list, instead you can use Collectors.toList()
to collect it in a list:
List<String> list = stream.peek(System.out::println)
.filter(p1.or(p2))
.collect(Collectors.toList()); // triggers the evaluation of the stream
System.out.println("Size = "+list.size());
In your example, streams are evaluated only when a terminal operation like
allMatch()
anyMatch()
noneMatch()
collect()
count()
forEach()
min()
max()
reduce()
are encountered.
回答2:
Since you haven't yet completed the stream operation i.e. peek
is an intermediate operation. You must use a terminal operation for that to be executed still.
Suggestion: Instead perform such operation using terminal operation such as collect
List<String> list = stream.peek(System.out::println)
.filter(p1.or(p2))
.collect(Collectors.toList());
Additionally: Adding a peek
post filter
to observe the values could be a little tricky in observation, as for the following code
List<String> list = stream.peek(System.out::println)
.filter(p1.or(p2))
.peek(System.out::println) // addition
.collect(Collectors.toList());
the output would look like :
one two two // filtered in three three // filtered in four five
回答3:
The streams are lazy. You mast call a terminal operation like forEach
:
stream.peek(System.out::println)
.filter(p1.or(p2))
.forEach(list::add);
In case you want to use peek
as intermediary operation for debugging purposes then you must call a terminal operation afterwards:
stream.peek(System.out::println)
.filter(p1.or(p2))
.peek(list::add);
.<any terminal operation here>();
Btw, if you want just store all the filtered values in a list, then better use collect(toList())
.
回答4:
All you've done with filter
and peek
is set up a chain of actions to apply to the stream. You haven't actually caused any of them to run yet. You have to add a terminal operation such as count
. (Another answer suggested using forEach
to add to the list, but I think you're specifically trying to use the intermediate operation peek
.)
来源:https://stackoverflow.com/questions/54510305/intermediate-operation-in-java-streams