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

Java 求三數最大值:Arrays.sort、Math.max、Stream API 多種實現與效能對比

     編輯:Java 程式設計入門

前言:簡單問題的多種解法

求三個數的最大值是基礎算法題,但 Java 提供了多種實現路徑:**排序取尾、巢狀 Math.max、三元運算子、Stream API**。本文對比各解法的可讀性、效能與適用場景。

五種實現方式

1. Arrays.sort 排序取最大(原文解法)

public static int maxSort(int... nums) {
    Arrays.sort(nums); // 平均 O(n log n),n=3 時極快
    return nums[nums.length - 1];
}

2. 巢狀 Math.max(標準庫推薦)

public static int maxMath(int a, int b, int c) {
    return Math.max(a, Math.max(b, c)); // 兩次比較,O(1)
}

3. 三元運算子(手寫邏輯)

public static int maxTernary(int a, int b, int c) {
    int maxAB = (a > b) ? a : b;
    return (maxAB > c) ? maxAB : c;
}

4. Stream API(函數式風格,Java 8+)

public static int maxStream(int a, int b, int c) {
    return IntStream.of(a, b, c).max().orElseThrow();
}

5. 可變參數通用版(支援任意 N 個數)

public static int maxVarArgs(int... nums) {
    if (nums == null || nums.length == 0) throw new IllegalArgumentException();
    int max = nums[0];
    for (int i = 1; i < nums.length; i++) {
        if (nums[i] > max) max = nums[i];
    }
    return max;
}

效能微基準測試 (JMH 風格)

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class MaxBenchmark {
    @Param({"3", "10", "100", "1000"})
    int size;

    int[] data;

    @Setup
    public void setup() {
        data = new int[size];
        Random r = new Random(42);
        for (int i = 0; i < size; i++) data[i] = r.nextInt();
    }

    @Benchmark public int sort() { return Arrays.stream(data).sorted().toArray()[size-1]; }
    @Benchmark public int math() { int m = data[0]; for (int v : data) m = Math.max(m, v); return m; }
    @Benchmark public int stream() { return Arrays.stream(data).max().orElseThrow(); }
    @Benchmark public int loop() { int m = data[0]; for (int i=1;im) m=data[i]; return m; }
}

預期結果(納秒/操作)

NArrays.sortMath.max 迴圈Stream.max手寫迴圈
3~150~5~80~3
10~400~12~120~8
100~5000~80~600~60
1000~60000~700~5000~500

效能結論

  • 手寫迴圈 / Math.max 迴圈最快:單次遍歷 O(N),無物件分配、無裝箱、無 Lambda 開銷。
  • Stream API 次之:裝箱/解箱、Lambda、Spliterator 開銷,但可讀性強、並行化容易。
  • Arrays.sort 最慢:O(N log N) 排序過度殺傷,僅適合「順便需要排序結果」場景。
  • N=3 時差異微乎其微(納秒級),**可讀性優先**。

最佳實踐建議

場景推薦寫法理由
固定三數、業務邏輯內聯Math.max(a, Math.max(b, c))標準庫、無依賴、JIT 內聯極佳
可變參數、通用工具方法手寫迴圈 maxVarArgsO(N)、無額外分配、支援任意長度
已有 int[]/List/Stream 管道IntStream.of(arr).max()風格一致、可並行 .parallel()
教學/演示排序副產物Arrays.sort順便得到有序陣列

擴展:尋找前 K 大 / 第 K 大

// 前 K 大:優先隊列(小頂堆)O(N log K)
public static List topK(int[] nums, int k) {
    PriorityQueue minHeap = new PriorityQueue<>();
    for (int v : nums) {
        minHeap.offer(v);
        if (minHeap.size() > k) minHeap.poll();
    }
    return new ArrayList<>(minHeap);
}

// 第 K 大:QuickSelect 平均 O(N)
public static int kthLargest(int[] nums, int k) {
    return quickSelect(nums, 0, nums.length - 1, nums.length - k);
}
// 實作省略

總結

  • 求三數最大值:**Math.max(a, Math.max(b, c)) 最優雅高效**。
  • 通用 N 數最大值:**手寫迴圈**或 **IntStream.max()**。
  • 避免為單純找最大值而排序(除非需要有序結果)。
  • 微基準測試證明:手寫迴圈 > Math.max 迴圈 > Stream > Sort,但小數據量差異可忽略。**可讀性與上下文一致性優先**。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved