Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between stream.max(Comparator) and stream.collect(Collectors.maxBy(Comparator) in Java

In Java Streams - what is the difference between stream.max(Comparator) and stream.collect(Collectors.maxBy(Comparator)) in terms of preformance. Both will fetch the max based on the comparator being passed. If this is the case why do we need the additional step of collecting using the collect method? When should we choose former vs latter? What are the use case scenarios suited for using both?

like image 677
Jay. Ni Avatar asked Nov 30 '22 14:11

Jay. Ni


2 Answers

They do the same thing, and share the same code.

why do we need the additional step of collecting using the collect method?

You don't. Use max() if that's what you want to do. But there are cases where a Collector can be handy. For example:

Optional<Foo> result = stream.collect(createCollector());

where createCollector() would return a collector based on some condition, which could be maxBy, minBy, or something else.

In general, you shouldn't care too much about the small performance differences that might exist between two methods that do the same thing, and have a huge chance of being implemented the same way. Instead, you should make your code as clear and readable as possible.

like image 178
JB Nizet Avatar answered Dec 04 '22 11:12

JB Nizet


There is a relevant quote in Effective Java 3rd Edition, page 214:

The collectors returned by the counting method are intended only for use as downstream collectors. The same functionality is available directly on Stream, via the count method, so there is never a reason to say collect(counting()). There are fifteen more Collectors with this property.

Given that maxBy is duplicated by Stream.max, it is presumably one of these sixteen methods.

Shortly after, same page, it goes on to justify the dual existence:

From a design perspective, these collectors represent an attempt to partially duplicate the functionality of streams in collectors so that downstream collectors can act as "ministreams".

Personally, I find this edict and explanation a bit unsatisfying: it says that it wasn't the intent for these 16 collectors to be used like this, but not why they shouldn't.

I suppose that the methods directly on stream are able to be implemented in specialized ways which could be more efficient than the general collectors.

like image 40
Andy Turner Avatar answered Dec 04 '22 11:12

Andy Turner