手动for循环遍历找最大值最稳妥:先判空,max初始化为arr[0],再从i=1开始比较;Arrays.stream有类型、空值、性能等多重陷阱;排序取末元素则时间复杂度升至O(n log n)且修改原数组。

用 for 循环遍历找最大值最稳妥
数组没排序、又不想引入额外依赖时,手动遍历是唯一可靠方式。别图省事直接用 Arrays.stream,尤其在老 JDK 或性能敏感场景下。
- 初始化
max必须用数组第一个元素,不能设成0或Integer.MIN_VALUE——数组可能全为负数或为空 - 空数组要提前判空,否则
array[0]抛ArrayIndexOutOfBoundsException - 基本类型数组(如
int[])没法用泛型流,Arrays.stream(intArr)返回的是IntStream,不是Stream<integer></integer>,这点容易混淆
int[] arr = {3, -1, 7, 2};
if (arr.length == 0) throw new IllegalArgumentException("empty array");
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) max = arr[i];
}
Arrays.stream 在 JDK 8+ 中可用但有陷阱
它写起来短,但默认只适合非空数组,且对基本类型和引用类型行为不一致。
-
int[]调用Arrays.stream(arr).max().orElseThrow()可以,但.max()返回的是OptionalInt,不是Optional<Integer> -
Integer[](包装类)才能用Stream.max(Comparator.naturalOrder()),否则编译不过 - 如果数组为
null,Arrays.stream(null)直接抛NullPointerException,比循环更脆 - 小数组看不出差别,但高频调用时,流式写法有对象创建开销(
IntStream实例、装箱等)
int[] arr = {3, -1, 7, 2};
int max = Arrays.stream(arr).max().orElseThrow(); // OK for int[]
// Integer[] arr2 = {3, -1, 7, 2};
// Integer max2 = Arrays.stream(arr2).max(Comparator.naturalOrder()).orElseThrow(); // OK for Integer[]
别忽略 Arrays.sort 的隐含成本
有人想“先排序再取最后一个”,这在逻辑上成立,但实际是典型过杀:时间复杂度从 O(n) 升到 O(n log n),还修改了原数组(除非拷贝)。
-
Arrays.sort(arr)是原地排序,后续所有对arr的读取都看到乱序结果 - 如果只是找最大值,排序做的大量比较和交换全是冗余计算
- 对大数组,GC 压力也明显——比如排序
Integer[]会触发大量装箱对象分配
多维数组最大值得自己展开
Arrays.stream 对二维数组(如 int[][])只流外层数组,不会自动扁平化。想用流必须显式 flatMap,反而更啰嗦。
立即学习“Java免费学习笔记(深入)”;
-
Arrays.stream(matrix).flatMapToInt(Arrays::stream).max()才能拿到整个二维数组最大值 - 但一旦涉及空行(某
matrix[i]为null),Arrays::stream就崩,得加过滤 - 这种场景下,嵌套
for循环反而更直白、更容易加空值防护









