Java 实例 – 数组并集(超详细)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在 Java 编程中,数组作为基础数据结构,经常需要进行合并、去重等操作。其中,“数组并集”是指将两个或多个数组中的元素合并为一个无重复的新数组。这一操作看似简单,但实现过程中会涉及算法效率、数据结构选择等核心知识点。本文将通过循序渐进的方式,结合代码示例和实际案例,深入讲解 Java 中数组并集的实现方法,并帮助读者理解其背后的逻辑原理。
数组并集的基础概念与应用场景
什么是数组并集?
数组并集(Array Union)是指将两个或多个数组中的元素合并成一个新数组,且新数组中不包含重复元素。例如,若数组 A = [1, 2, 3]
和数组 B = [3, 4, 5]
进行并集操作,结果应为 [1, 2, 3, 4, 5]
。
实际应用场景
数组并集在编程中常见于以下场景:
- 数据合并:如电商系统需要合并不同来源的商品列表,去重后展示。
- 数据清洗:合并多个日志文件中的记录,去除重复条目。
- 算法优化:在算法竞赛或复杂逻辑中,快速合并多个数据集。
手动实现数组并集:基础方法与缺陷分析
基础实现思路
手动实现数组并集的核心步骤如下:
- 遍历源数组:逐个读取两个数组的所有元素。
- 去重操作:将元素存入临时存储空间(如
List
),并通过检查是否已存在来避免重复。 - 转换为数组:将最终结果从临时存储转换为目标数组格式。
示例代码:手动实现
public static int[] arrayUnion(int[] arr1, int[] arr2) {
List<Integer> tempList = new ArrayList<>();
// 遍历第一个数组
for (int num : arr1) {
if (!tempList.contains(num)) {
tempList.add(num);
}
}
// 遍历第二个数组
for (int num : arr2) {
if (!tempList.contains(num)) {
tempList.add(num);
}
}
// 转换为数组
int[] result = new int[tempList.size()];
for (int i = 0; i < result.length; i++) {
result[i] = tempList.get(i);
}
return result;
}
方法缺陷分析
上述方法虽然简单易懂,但存在以下问题:
- 效率问题:
contains()
方法的时间复杂度为 O(n),导致整体时间复杂度为 O(n²),当数组规模较大时性能较差。 - 代码冗余:需要遍历两个数组并重复检查逻辑,扩展性差(例如合并三个数组时代码需大幅修改)。
借助集合类优化:使用 HashSet
和 Arrays
工具类
集合类的优势
Java 的 HashSet
是基于哈希表实现的集合,其 add()
方法的时间复杂度接近 O(1),能显著提升去重效率。结合 Arrays
工具类,可以简化代码逻辑。
示例代码:集合类实现
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public static int[] arrayUnionWithSet(int[] arr1, int[] arr2) {
// 将数组转换为 Set 去重
Set<Integer> set = new HashSet<>();
set.addAll(Arrays.stream(arr1).boxed().toList());
set.addAll(Arrays.stream(arr2).boxed().toList());
// 转换为数组
Integer[] tempArray = set.toArray(new Integer[0]);
// 强转为基本类型数组
int[] result = Arrays.stream(tempArray).mapToInt(Integer::intValue).toArray();
return result;
}
关键点解析
- 自动装箱与流式操作:
Arrays.stream(arr1).boxed()
将基本类型数组转换为IntStream
,再通过boxed()
转为Stream<Integer>
。toList()
方法将流转换为List
,便于addAll()
操作。
- 数组类型转换:
Set
转为Integer[]
后,通过mapToInt
将包装类型转为基本类型int[]
。
进阶优化:时间复杂度与空间复杂度的权衡
算法复杂度分析
方法 | 时间复杂度 | 空间复杂度 |
---|---|---|
手动遍历(基础方法) | O(n²) | O(n) |
集合类优化方法 | O(n) | O(n) |
优化策略总结
- 优先选择集合类:对于中大型数据集,
HashSet
的 O(n) 复杂度是更优选择。 - 避免重复遍历:通过流式操作一次性处理多个数组。
- 类型适配:根据需求选择基本类型数组或对象数组,避免不必要的装箱操作。
实际案例:电商商品合并场景
案例背景
某电商平台需要合并两个商品库的 ID 列表,确保最终结果无重复且顺序无关紧要。
数据准备
// 商品库 A 的 ID 列表
int[] productIdsA = {1001, 1002, 1003, 1004};
// 商品库 B 的 ID 列表
int[] productIdsB = {1003, 1004, 1005, 1006};
调用优化方法
int[] mergedIds = arrayUnionWithSet(productIdsA, productIdsB);
System.out.println("合并后的商品 ID 数组:" + Arrays.toString(mergedIds));
输出结果
合并后的商品 ID 数组:[1001, 1002, 1003, 1004, 1005, 1006]
案例总结
通过集合类方法,代码简洁且性能高效,完美适配实际业务需求。
常见问题与解决技巧
问题 1:合并多个数组时如何扩展代码?
解答:
使用可变参数和循环遍历所有数组:
public static int[] arrayUnionWithSet(int[]... arrays) {
Set<Integer> set = new HashSet<>();
for (int[] arr : arrays) {
set.addAll(Arrays.stream(arr).boxed().toList());
}
// 后续转换逻辑与之前相同
return ...;
}
问题 2:如何保持合并后的数组元素顺序?
解答:
若需保留原始顺序,可改用 LinkedHashSet
替代 HashSet
,它能维护插入顺序。
结论
通过本文的讲解,读者可以掌握 Java 中数组并集的两种实现方法:基础的手动遍历法和高效的集合类法。对于编程初学者,建议先理解手动实现的逻辑,再逐步过渡到集合类的优化方案;对于中级开发者,则需关注算法复杂度分析和实际场景适配。
在开发过程中,合理选择数据结构(如 HashSet
)和工具类(如 Arrays
)是提升代码质量的关键。未来,随着项目需求的复杂化,读者还可进一步探索多线程并行处理或分布式计算的优化方案,但万变不离其宗,扎实的数组操作基础是进阶的前提。