Contents

Java的数组中查找最小/最大

1. 简介

在这个简短的教程中,我们将了解如何使用 Java 8 的Stream API 在数组中查找最大值和最小值。 我们将从在整数数组中找到最小值开始,然后在对象数组中找到最大值。

2. 概述

有很多方法可以在无序数组中找到最小值或最大值,它们看起来都像:

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

我们将看看Java 8 如何对我们隐藏这些细节。但是,如果 Java 的 API 不适合我们,我们总是可以回到这个基本算法。

因为我们需要检查数组中的每个值,所以所有实现都是$$ O(n) $$。

3. 寻找最小值

java.util.stream.IntStream接口提供了min方法,**可以很好地满足我们的目的。

因为我们只使用整数,所以min不需要Comparator

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

请注意我们如何使用Arrays中的stream静态方法创建integer流对象。每个原始数组类型都有等效的stream方法。

由于数组可能为空,min返回一个Optional,因此要将其转换为int,我们使用getAsInt

4. 找到最大的自定义对象

让我们创建一个简单的 POJO:

public class Car {
    private String model;
    private int topSpeed;
    // standard constructors, getters and setters
}

然后我们可以再次使用Stream API 在 Car 数组中找到最快的Car

@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);
}

在这种情况下,Arrays的静态方法stream返回接口java.util.stream.Stream<T>的实例,其中方法max需要Comparator*。

我们本可以构建自己的自定义Comparator,但Comparator.comparing 更容易。

再次注意max出于与以前相同的原因返回一个Optional实例。

我们可以get这个值,也可以用Optional做任何其他可能的事情,比如orElseThrow,如果max没有返回值就会抛出异常。