Java streams 26. Collect 2. The .maxBy() and .minBy() collectors

Terminal operation either returns one value (of the same or another type than the type of the input) or does not return anything at all (produces just side effects). It does not allow another operation to be applied after it and closes the stream.

In this post, we will continue covering the last of the terminal operations called collect():

R collect(Collector<T,A,R> collector)

It allows implementing a vast variety of algorithms using the ready-to-use implementations of collectors created by factory methods of the java.util.stream.Collectors class. 

As before, in our code examples, we will use the Box class:

   
  class Box {
     private int weight;
     private String color;
     public Box(){}
     public Box(int weight, String color) {
        this.weight = weight;
        this.color = color;
     }
     public int getWeight() { return weight; }
     public void setWeight(int weight) { 
        this.weight = weight; 
     }
     public String getColor() { return color; }
     public void setColor(String color) { 
         this.color = color; 
        }
     @Override
     public String toString() {
        return "Box{weight=" + weight +
                    ", color='" + color + "'}";
     }
  }
     


Collectors.maxBy() collector

The signature of Collectors.maxBy() factory method looks as follows:

static Collector<T, ?, Optional<T>> maxBy​(Comparator<T> comparator)

It creates a Collector that calculates the max element according to a given Comparator, described as an Optional.

We have seen already the example of its usage in Java streams 25. Collect 1. Custom collector

   
  Box theHeaviest = Stream.of(new Box(5, "rhowed"),
                              new Box(8, "green"),
                              new Box(3, "blue"))
      .collect(Collectors.maxBy(Comparator
                         .comparing(Box::getWeight)))
      .orElse(null);
  System.out.print(theHeaviest); 
                //prints: Box{weight=8, color='green'}
    

There is no guarantee that the max element will be found (if a stream is empty, for example), so the operation returns result wrapped by an Optional object.

Please, notice that this implementation cannot be used for finding the max element in a parallel stream. That would be the reason for using the max() operation described in Java streams 22. FindAny, findFirst, max, min or for creating a custom collector.

We could avoid boxing/unboxing while comparing two primitive integers and use the comparator Compartor.comparingInt() as shown in the following example: 

  
  Box theHeaviest = Stream.of(new Box(5, "red"),
                              new Box(8, "green"),
                              new Box(3, "blue"))
     .collect(Collectors.maxBy(Comparator
                        .comparingInt(Box::getWeight))) 
     .orElse(null);
  System.out.print(theHeaviest);      
                //prints: Box{weight=8, color='green'}
         

The collector that calculates the minimal element and its usage are quite similar.



Collectors.minBy() collector

The signature of Collectors.maxBy() factory method looks as follows:

static Collector<T, ?, Optional<T>> maxBy​(Comparator<T> comparator)

It creates a Collector that calculates the max element according to a given Comparator, described as an Optional.

The following are examples of its usage:

   
  Box theLightest = Stream.of(new Box(5, "red"),
                              new Box(8, "green"),
                              new Box(3, "blue"))
     .collect(Collectors.minBy(Comparator
                        .comparing(Box::getWeight)))  
     .orElse(null);
  System.out.print(theLightest);                     
               //prints: Box{weight=3, color='blue'}

  theLightest = Stream.of(new Box(5, "red"),
                          new Box(8, "green"),
                          new Box(3, "blue"))
     .collect(Collectors.minBy(Comparator
                        .comparingInt(Box::getWeight))) 
     .orElse(null);
  System.out.print(theLightest);          
                  //prints: Box{weight=3, color='blue'}
             

In the next post, we will continue discussing the collect() operation and demonstrate usage of the ready-to-use collectors that calculate some statistics of the stream elements – sum, average, min, and max (yes, yet another way to get min and max; you have quite a selection to choose from).

See other posts on Java 8 streams and posts on other topics.
You can also use navigation pages for Java stream related blogs:
— Java 8 streams blog titles
— Create stream
— Stream operations
— Stream operation collect()
The source code of all the code examples is here in GitHub

, ,

Send your comments using the link Contact or in response to my newsletter.
If you do not receive the newsletter, subscribe via link Subscribe under Contact.

Powered by WordPress. Designed by Woo Themes