
本文介绍如何利用 java 8 的 stream api 高效查找两个 int 数组之间的重复元素,替代传统的嵌套循环方式,代码更简洁、可读性更强,并兼顾性能与函数式编程风格。
本文介绍如何利用 java 8 的 stream api 高效查找两个 int 数组之间的重复元素,替代传统的嵌套循环方式,代码更简洁、可读性更强,并兼顾性能与函数式编程风格。
在 Java 8 中,借助 Stream 和集合操作,我们可以优雅地实现跨数组去重与交集识别。核心思路是:将两个数组合并为一个流,利用 Set::add 方法的返回值(首次添加返回 true,重复添加返回 false)作为过滤条件,从而精准捕获所有出现次数 ≥2 的元素——即两个数组的公共值。
以下为完整实现示例:
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FindDuplicatesWithStream {
public static void main(String[] args) {
int[] arr1 = {1, 2, 3, 4};
int[] arr2 = {2, 3, 5, 6};
Set<Integer> seen = new HashSet<>();
List<Integer> duplicates = Stream.concat(
Arrays.stream(arr1).boxed(),
Arrays.stream(arr2).boxed())
.filter(i -> !seen.add(i)) // add() 返回 false 表示已存在 → 即为重复项
.collect(Collectors.toList());
System.out.println("Duplicates: " + duplicates); // 输出: [2, 3]
}
}✅ 关键说明:
-
Arrays.stream(arr).boxed()将原始int[]转为Stream<integer></integer>,因HashSet和大多数 Stream 操作不支持原始类型流(IntStream)的直接集合交互; -
Stream.concat(s1, s2)合并两个流,顺序为arr1元素先于arr2元素; -
seen.add(i)是“副作用”操作,但在此处安全且高效:它既完成去重记录,又通过返回值提供判断依据; - 最终结果为
List<integer></integer>,自动去重(每个重复值仅出现一次),符合语义上“找出哪些元素同时存在于两数组中”。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 此方法返回的是所有在合并流中第二次及以后出现的元素,因此若某元素在
arr1中出现两次、arr2中无该元素,它也会被误判为重复。如需严格限定为“在arr1和arr2中各至少出现一次”,应改用交集逻辑(例如Arrays.stream(arr1).boxed().filter(set2::contains).distinct().toList()); - 若需保持原始顺序或处理大数据量,建议先将
arr2转为Set<integer></integer>提升查找效率,再对arr1流式过滤(见进阶写法):
Set<Integer> set2 = Arrays.stream(arr2).boxed().collect(Collectors.toSet());
List<Integer> intersection = Arrays.stream(arr1)
.boxed()
.filter(set2::contains)
.distinct()
.collect(Collectors.toList());该方案时间复杂度为 O(n + m),显著优于传统双循环的 O(n × m),是现代 Java 开发中推荐的实践方式。


















