Last week, I described a use-case for a custom Stream
Collector
. I received a intriguing comment on Twitter:Hats off to you, Miguel! Your comment revealed a method I didn’t know!
So I decided to investigate what is the
teeing()
method about.Returns a Collector that is a composite of two downstream collectors. Every element passed to the resulting collector is processed by both downstream collectors, then their results are merged using the specified merge function into the final result.
The resulting collector functions do the following:
* supplier: creates a result container that contains result containers obtained by calling each collector’s supplier
* accumulator: calls each collector’s accumulator with its result container and the input element
* combiner: calls each collector’s combiner with two result containers
* finisher: calls each collector’s finisher with its result container, then calls the supplied merger and returns its result.
— JavaDocs
We can indeed replace our custom
Collector
with two simple Collector
implementations, one aggregating price rows and the other summing the cart’s price.Let’s look at the final code and explain it line by line.
public PriceAndRows getPriceAndRows(Cart cart) {
return cart.getProducts()
.entrySet()
.stream()
.map(CartRow::new) // 1
.collect(Collectors.teeing( // 2
Collectors.reducing( // 3
BigDecimal.ZERO, // 4
CartRow::getRowPrice, // 5
BigDecimal::add), // 6
Collectors.toList(), // 7
PriceAndRows::new // 8
));
}
Entry
to a CartRow
teeing()
methodreducing()
call, with:Price
from a CartRow
BinaryOperator
to add two prices togetherCartRow
into a listOn the implementation side,
teeing()
:Collector
, i.e., supplier()
, accumulator()
, combiner()
and finisher()
Collector
by passing the pairsThus, there will be a single Collector and a single pass in the end.
I hope this post made you consider using
teeing()
before creating a custom Collector
. Thanks again to Miguel!By the way, I’m always happy to learn new things. In case you’ve got
insights to share, you can use the commenting system below or Twitter.
The complete source code for this post can be found on Github in Maven format.
Originally published at A Java Geek on May 9th, 2021