1. 概述
本文将探讨两种在Java中查找二维数组极值(最小值和最大值)的技术。二维数组本质上是网格状的数据结构,可以看作是数组的数组,其中每个内部数组代表网格的一行。
我们将首先分析使用嵌套for循环的传统方法,随后研究如何利用Stream API实现相同目标。两种方法各有优劣,具体选择取决于实际需求。
2. 使用嵌套for循环查找极值
@Test
void givenArrayWhenFindMinAndMaxUsingForLoopsThenCorrect() {
int[][] array = {{8, 4, 1}, {2, 5, 7}, {3, 6, 9}};
int min = array[0][0];
int max = array[0][0];
for (int[] row : array) {
for (int currentValue : row) {
if (currentValue < min) {
min = currentValue;
} else if (currentValue > max) {
max = currentValue;
}
}
}
assertEquals(1, min);
assertEquals(9, max);
}
核心逻辑分解:
- 外层循环遍历二维数组的每一行
- 内层循环遍历当前行的每个元素
- 通过比较更新最小值和最大值
✅ 优点:逻辑直观,代码简单
❌ 缺点:处理大型数组时效率较低
3. 使用Stream API查找极值
Java Stream API提供了声明式的数据处理方式。我们可以通过flatMapToInt()
方法将二维数组转换为单元素流,再利用summaryStatistics()
方法一行搞定极值统计:
@Test
void givenArrayWhenFindMinAndMaxUsingStreamThenCorrect() {
int[][] array = {{8, 4, 1}, {2, 5, 7}, {3, 6, 9}};
IntSummaryStatistics stats = Arrays
.stream(array)
.flatMapToInt(Arrays::stream)
.summaryStatistics();
assertEquals(1, stats.getMin());
assertEquals(9, stats.getMax());
}
关键步骤解析:
Arrays.stream(array)
:将二维数组转为流flatMapToInt(Arrays::stream)
:扁平化处理,将嵌套结构转为单元素流summaryStatistics()
:生成包含极值、平均值、总和等统计信息的对象
⚠️ 注意:如果只需要极值而不需要其他统计信息,可直接使用min()
和max()
方法更高效
3.1. 并行处理优化
针对大型数组,可使用并行流提升处理效率。通过多线程分发计算负载,显著减少处理时间:
@Test
void givenArrayWhenFindMinAndMaxUsingParallelStreamThenCorrect() {
int[][] array = {{8, 4, 1}, {2, 5, 7}, {3, 6, 9}};
IntSummaryStatistics stats = Arrays
.stream(array)
.parallel()
.flatMapToInt(Arrays::stream)
.summaryStatistics();
assertEquals(1, stats.getMin());
assertEquals(9, stats.getMax());
}
✅ 优势:充分利用多核CPU性能
⚠️ 踩坑点:小型数组可能因线程调度开销反而降低性能
4. 总结
本文对比了两种二维数组极值查找方案:
- 嵌套循环:适合追求代码可读性的场景,逻辑直观但性能一般
- Stream API:简洁高效,尤其适合大型数组处理,并行流可进一步优化性能
经验之谈:日常开发中,小型数组用循环更直观,大型数据集果断上Stream。代码示例已上传至GitHub仓库,欢迎参考。