I've noticed many functionalities exposed in Stream are apparently duplicated in Collectors, such as Stream.map(Foo::bar)
versus Collectors.mapping(Foo::bar, ...)
, or Stream.count()
versus Collectors.counting()
. What's the difference between these approaches? Is there a performance difference? Are they implemented differently in some way that affects how well they can be parallelized?
Stream map(Function mapper) returns a stream consisting of the results of applying the given function to the elements of this stream. Stream map(Function mapper) is an intermediate operation. These operations are always lazy.
Filter takes a predicate as an argument so basically you are validating your input/collection against a condition, whereas a map allows you to define or use a existing function on the stream eg you can apply String.
The mapping() method mapping() is a static method of the Collectors class that returns a Collector . It converts a Collector accepting elements of one type to a Collector that accepts elements of another type. This method is generally used in multi-level reduction operations.
The map() method wraps the underlying sequence in a Stream instance, whereas the flatMap() method allows avoiding nested Stream<Stream<R>> structure. Here, map() produces a Stream consisting of the results of applying the toUpperCase() method to the elements of the input Stream: List<String> myList = Stream.
The collectors that appear to duplicate functionality in Stream
exist so they can be used as downstream collectors for collector combinators like groupingBy()
.
As a concrete example, suppose you want to compute "count of transactions by seller". You could do:
Map<Seller, Long> salesBySeller =
txns.stream()
.collect(groupingBy(Txn::getSeller, counting()));
Without collectors like counting()
or mapping()
, these kinds of queries would be much more difficult.
There's a big difference. The stream operations could be divided into two group:
Stream.map
, Stream.flatMap
, Stream.filter
. Those produce instance of the Stream and are always lazy, e.g. no actual traversal of the Stream elements happens. Those operations are used to create transformation chain.Stream.collect
, Stream.findFirst
, Stream.reduce
etc. Those do the actual work, e.g. perform the transformation chain operations on the stream, producing a terminal value. Which could be a List, count of element, first element etc.Take a look at the Stream package summary javadoc for more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With