1. Introduction

In this short tutorial, we’re going to see how to find the maximum and the minimum values in an array, using Java 8’s Stream API.

We’ll start by finding the minimum in an array of integers, and then we’ll find the maximum in an array of objects.

2. Overview

There are many ways of finding the min or max value in an unordered array, and they all look something like:

SET MAX to array[0]
FOR i = 1 to array length - 1
  IF array[i] > MAX THEN
    SET MAX to array[i]
  ENDIF
ENDFOR

We’re going to look at how Java 8 can hide these details from us. But, in cases where Java’s API doesn’t suit us, we can always go back to this basic algorithm.

Because we need to check each value in the array, all implementations are O(n).

3. Finding the Smallest Value

The java.util.stream.IntStream interface provides the min method that will work just fine for our purposes.

As we are only working with integers, min doesn’t require a Comparator:

@Test
public void whenArrayIsOfIntegerThenMinUsesIntegerComparator() {
    int[] integers = new int[] { 20, 98, 12, 7, 35 };
    
    int min = Arrays.stream(integers)
      .min()
      .getAsInt();

    assertEquals(7, min);
}

Notice how we created the Integer stream object using the stream static method in Arrays. There are equivalent stream methods for each primitive array type.

Since the array could be empty, min returns an Optional, so to convert that to an int, we use getAsInt.

4. Finding the Largest Custom Object

Let’s create a simple POJO:

public class Car {
    private String model;
    private int topSpeed;

    // standard constructors, getters and setters
}

And then we can use the Stream API again to find the fastest car in an array of Cars:

@Test
public void whenArrayIsOfCustomTypeThenMaxUsesCustomComparator() {
    Car porsche = new Car("Porsche 959", 319);
    Car ferrari = new Car("Ferrari 288 GTO", 303);
    Car bugatti = new Car("Bugatti Veyron 16.4 Super Sport", 415);
    Car mcLaren = new Car("McLaren F1", 355);
    Car[] fastCars = { porsche, ferrari, bugatti, mcLaren };

    Car maxBySpeed = Arrays.stream(fastCars)
      .max(Comparator.comparing(Car::getTopSpeed))
      .orElseThrow(NoSuchElementException::new);

    assertEquals(bugatti, maxBySpeed);
}

In this case, the static method stream of Arrays returns an instance of the interface java.util.stream.Stream where the method max requires a Comparator.

We could’ve constructed our own custom Comparator, but Comparator.comparing is much easier.

Note again that max returns an Optional instance for the same reason as before.

We can either get this value, or we can do whatever else is possible with Optionals, like orElseThrow that throws an exception if max doesn’t return a value.

5. Conclusion

We saw in this short article how easy and compact it is to find max and min on an array, using the Stream API of Java 8.

For more information on this library please refer to the Oracle documentation.

The implementation of all these examples and code snippets can be found over on GitHub.