首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 獲取數組最大值與最小值:基礎算法與 Stream API 多種實現

     編輯:Java 相關知識

前言

獲取數組最大值、最小值是基礎算法題,也是日常開發常見需求。本文提供傳統循環、Arrays 工具類、Stream API 三種實現,並分析時間複雜度、適用場景與邊界條件處理。

一、 傳統雙循環實現(教學級)

public static void findMinMax(int[] array) {
    if (array == null || array.length == 0) {
        throw new IllegalArgumentException("數組不能為空");
    }
    int max = array[0];
    int min = array[0];
    
    for (int i = 1; i < array.length; i++) {
        if (array[i] > max) max = array[i];
    }
    for (int i = 1; i < array.length; i++) {
        if (array[i] < min) min = array[i];
    }
    
    System.out.println("最大值: " + max);
    System.out.println("最小值: " + min);
}
  • 時間複雜度:O(2n) = O(n),兩次遍歷。
  • 空間複雜度:O(1)。
  • 可優化為單次遍歷同時更新 max/min。

二、 單次遍歷優化版

public static void findMinMaxSinglePass(int[] array) {
    if (array == null || array.length == 0) throw new IllegalArgumentException("數組不能為空");
    int max = array[0];
    int min = array[0];
    for (int i = 1; i < array.length; i++) {
        int val = array[i];
        if (val > max) max = val;
        else if (val < min) min = val; // else if 微優化:若大於 max 則不可能小於 min
    }
    System.out.println("最大值: " + max + ", 最小值: " + min);
}

三、 Arrays.sort() 排序取值(不推薦大數組)

public static void findMinMaxSort(int[] array) {
    if (array == null || array.length == 0) throw new IllegalArgumentException("數組不能為空");
    int[] copy = Arrays.copyOf(array, array.length); // 避免修改原數組
    Arrays.sort(copy);
    System.out.println("最小值: " + copy[0] + ", 最大值: " + copy[copy.length - 1]);
}
  • 時間複雜度:O(n log n),顯著劣於 O(n)。
  • 需複製數組避免副作用,額外空間 O(n)。
  • 僅適合極小數組或後續還需有序數組的場景。

四、 Java 8 Stream API 實現(推薦現代項目)

public static void findMinMaxStream(int[] array) {
    if (array == null || array.length == 0) throw new IllegalArgumentException("數組不能為空");
    
    IntSummaryStatistics stats = Arrays.stream(array).summaryStatistics();
    System.out.println("最大值: " + stats.getMax() + ", 最小值: " + stats.getMin());
    // 同時獲得 count、sum、average 等統計信息
}
  • 單次遍歷獲得最大/最小/總和/平均/計數,功能最豐富。
  • 內部優化為單次遍歷,性能接近手寫循環。
  • 代碼聲明式、可讀性強,易於並行化 Arrays.stream(array).parallel().summaryStatistics()。

五、 通用化:支持任意 Comparable 類型

public static <T extends Comparable<T>> MinMax<T> findMinMax(T[] array) {
    if (array == null || array.length == 0) throw new IllegalArgumentException("數組不能為空");
    T max = array[0];
    T min = array[0];
    for (int i = 1; i < array.length; i++) {
        if (array[i].compareTo(max) > 0) max = array[i];
        else if (array[i].compareTo(min) < 0) min = array[i];
    }
    return new MinMax<>(min, max);
}

static class MinMax<T> {
    final T min, max;
    MinMax(T min, T max) { this.min = min; this.max = max; }
    @Override public String toString() { return "MinMax{min=" + min + ", max=" + max + "}"; }
}

六、 邊界條件與異常處理清單

情況處理建議
null 數組拋 IllegalArgumentException 或返回 Optional.empty()
空數組 (length==0)同 null,業務決定是否允許
單元素數組max == min == 該元素,正常返回
包含 NaN (float/double)比較語義特殊,建議用 Double.compare / Float.compare
大數據量並行Stream.parallel() 或 ForkJoinPool 自定義任務

七、 基準測試參考 (JMH)

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MinMaxBenchmark {
    private int[] data = new int[10000];
    @Setup public void setup() { new Random().nextInts(10000).forEach(i -> data[i] = i); }

    @Benchmark public void loop() { findMinMaxSinglePass(data); }
    @Benchmark public void stream() { findMinMaxStream(data); }
    @Benchmark public void sort() { findMinMaxSort(data); }
}

/* 典型結果 (10000 元素):
loop      ~ 15,000 ns/op
stream    ~ 18,000 ns/op (含統計對象創建開銷)
sort      ~ 1,200,000 ns/op (O(n log n) 顯著劣勢)
*/

八、 總結建議

  1. 極致性能、基本類型數組:手寫單次遍歷循環。
  2. 現代項目、代碼可讀性、需多統計指標:Arrays.stream(array).summaryStatistics() **首選**。
  3. 物件數組、自定義比較邏輯:泛型方法 + Comparable / Comparator。
  4. 避免排序法:除非後續確實需要有序數組。
  5. 務必處理 null/空數組,防止生產 NPE。

一行代碼 IntSummaryStatistics stats = Arrays.stream(arr).summaryStatistics(); 解決最大/最小/平均/求和/計數,是 Java 8+ 專案的標準答案。理解底層單次遍歷原理,才能在性能敏感場景做正確權衡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved