3

In java 8 , Stream API help us to do our job with very clean and with less number of code. I am big fan of these stream API. But there are few operations which kind of help in solving the same type of problem and not sure when to use which operations Although it is not that much hard to choose between but just want to know any one have any specific use case for these. Operation which i am talking about is :-

Intermediate Operations :- min and max

Terminal Operation: collect with Collectors class strategy using minBy and maxBy

List<String> randomString= Arrays.asList("AA","AAA","A","AAAA","AAAAAA","AAAAAAAAAAAAAAAAAA");
String maxByIntermediateMax = randomString.stream().max(String :: compareTo).get();
String minByIntermediateMin = randomString.stream().min(String :: compareTo).get();
System.out.println("Intermediate Min() :- "+minByIntermediateMin+" Intermeidate Max() :- "+ maxByIntermediateMax);
String minByCollectorsMinBy = randomString.stream().collect(Collectors.minBy(Comparator.naturalOrder())).get();
String maxByCollectorsMaxBy = randomString.stream().collect(Collectors.maxBy(Comparator.naturalOrder())).get();
System.out.println("Collectors MinBy :- "+minByCollectorsMinBy+ " , Collectors maxBy is :- "+maxByCollectorsMaxBy);

Output

Intermediate Min() :- A Intermeidate Max() :- AAAAAAAAAAAAAAAAAA
Collectors MinBy :- A , Collectors maxBy is :- AAAAAAAAAAAAAAAAAA
Gautham M
  • 4,816
  • 3
  • 15
  • 37
Mukesh
  • 540
  • 1
  • 9
  • 13
  • 3
    Basically the same consideration as in [Collectors.summingInt() vs mapToInt().sum()](https://stackoverflow.com/a/37025002/2711488) By the way, there is no need to create a new comparator via `String :: compareTo` when you already know about `Comparator.naturalOrder()`. – Holger Jun 16 '21 at 08:43
  • ... at least unless there are any performance benefits that one can prove. – Naman Jun 16 '21 at 09:03

3 Answers3

1

JavaDoc of Stream#min says that min is a terminal operation, so .collect(Collectors.minBy(...)) and .min(...) are interchangeable.

As for me, min and max have more readable syntax, but collect is more generic, so as an example, you can pass min/max collector as an argument of your method.

geobreze
  • 2,274
  • 1
  • 10
  • 15
1

Stream.min and Stream.max are terminal operations. The javadoc clearly states that.

The similarity between these two is what you have mentioned in your question. They both, using BinaryOperator.minBy(comparator) do a reducing operation to the elements (even though the implementation of how it is reduced is slightly different).

Hence there are no changes in output in your code. Since you need to find the min/max among all the stream elements, I would suggest using Stream.min for your case because the code would look neat and also you do not really need to create a collector in this case.

But there are scenarios where Collectors.minBy need to be used. Assume that you need to group your elements and need to find the min/max in each group. In such scenarios you cannot use Stream.min. Here you need to use Collectors.groupingBy(mapper, Collectors.minBy(...)). Similarly you could use it for partitionBy and other similar methods where you need a collector.

Gautham M
  • 4,816
  • 3
  • 15
  • 37
0

Using stream().max effectively produces the same result as stream().collect(Collectors.maxBy). The same is true for stream().min and stream().collect(Collectors.minBy)

While the results are the same, there are some subtle differences on the readability and flexibility offered from these 2 approaches.

By using Collectors you can use any collector returning an Optional<String>. The implementedmin and max are just some implemented versions of Collectors.reducing. You could also use any other Collectorsimilar to Collectors.reducing as an argument.

 List<String> randomString= Arrays.asList("AA","AAA","A","AAAA","AAAAAA","AAAAAAAAAAAAAAAAAA");
 Collector<String, ?, Optional<String>> collectorMin = Collectors.minBy(Comparator.naturalOrder());
 Collector<String, ?, Optional<String>> collectorMax = Collectors.minBy(Comparator.naturalOrder());
    
     
    String collectedMin= randomString.stream().collect(collectorMin ).get();
    String collectedMax= randomString.stream().collect(collectorMax ).get();

On the other hand stream().max/stream().min are much more readable and less verbose.

Spyros K
  • 2,480
  • 1
  • 20
  • 37