java 数组去重就是把数组里面重复出现的元素只保留一份,得到无重复元素的新数组,常用实现思路包含双重循环判断 Set 集合去重 Java8 Stream 去重 排序后相邻比对这几种,不同方案在是否保留原顺序 时间复杂度 代码简洁度上有明显差别。之所以需要专门写数组去重代码,是因为 java 原生数组本身长度固定,没有自带去重方法,数组创建之后不能直接删除元素,必须新建数组或者转换成集合完成去重再转回数组,这也是很多初学者写 java 数组去重容易踩坑的地方。实现的时候一般是先确认需求,要不要保留原始元素顺序,元素是基本类型还是对象类型,然后挑选对应的算法,编写代码完成去重,最后把去重之后的集合或者列表转回数组,测试重复元素边界情况,比如空数组 全部重复 没有重复元素这几种场景。完成代码之后就可以得到去重后的数组,面试里面 java 数组去重是高频基础题,经常要求手写实现并且分析时间复杂度。
一 方案一 Set 集合去重(最常用)
原理:HashSet 本身不允许存储重复元素,把数组全部元素存入 Set,自动剔除重复项,再把 Set 转回数组。
清单
1 优点 代码简洁,写法简单,开发项目优先选用
2 缺点 HashSet 是无序,如果需要保留原始顺序,要换成 LinkedHashSet
3 适用 数字 字符串这类可以正常 equals 和 hashCode 的元素
4 注意 对象数组去重,对象类必须重写 equals 和 hashCode,否则 Set 判定重复失效
二 方案二 双重循环去重(面试手写高频)
原理:外层循环取出每一个元素,内层循环对比后面元素,如果发现重复就标记,最后收集不重复元素。
表格
| 项目 | 说明 |
|---|---|
| 时间复杂度 | O (n²),数组很大的时候性能偏低 |
| 优点 | 不需要依赖集合,纯数组逻辑,适合面试手写 |
| 缺点 | 代码量大,大数组效率差 |
| 特点 | 可以保留原数组元素顺序 |
三 方案三 Java8 Stream 去重
原理:调用 Stream 的 distinct 方法,底层依靠 equals 和 hashCode 判断重复,去重之后转回数组。
清单
1 优点 一行链式代码,写法优雅,是现代 java 项目推荐写法
2 特点 distinct 默认保留元素第一次出现的顺序
3 适用 JDK8 及以上版本
4 局限 对象元素同样要求重写 equals 和 hashCode
四 方案四 排序 + 相邻比对去重
原理:先对原数组排序,排序之后相同元素会相邻,遍历的时候只和前一个元素对比,不一样就保留。
清单
1 优点 时间复杂度 O (nlogn),比双重循环快很多
2 缺点 原数组顺序会被打乱,不适合要求保留原始顺序场景
3 适用 数字数组,允许改变元素原有排序
4 注意 排序之后边界要处理,避免数组下标越界
五 不同方案对比总结
表格
| 实现方式 | 是否保留原顺序 | 时间复杂度 | 代码难度 |
|---|---|---|---|
| LinkedHashSet | 保留 | O(n) | 简单 |
| HashSet | 不保留 | O(n) | 简单 |
| 双重循环 | 保留 | O(n²) | 中等 |
| Stream distinct | 保留 | O(n) | 简单 |
| 排序相邻比对 | 不保留 | O(nlogn) | 中等 |
六 常见踩坑点
清单
1 基本类型数组 int [] 不能直接转成 HashSet,需要转成包装类 Integer,或者循环遍历逐个添加
2 对象数组 java 数组去重失败,绝大多数原因是没有重写 equals 和 hashCode
3 原数组长度固定,去重之后元素数量变少,不能原地修改原数组长度,必须新建数组
4 空数组 null 元素,代码要提前判断,避免空指针异常
【常见问题】
问题 1 java 数组去重为什么推荐 LinkedHashSet
回答 1 java 数组去重使用 LinkedHashSet 可以在自动去除重复元素的同时保留原始元素顺序,普通 HashSet 会打乱顺序,如果业务要求保持原顺序,LinkedHashSet 是 java 数组去重非常合适的方案。
问题 2 java 数组去重双重循环和 Stream 哪个性能更好
回答 1 大数组场景 Stream 去重性能优于双重循环,双重循环是 O (n²),数据量大的时候效率明显下降,java 数组去重优先 Stream 或者 Set,双重循环一般只用于面试手写考察算法思路。
问题 3 java 对象数组去重为什么不生效
回答 1 java 对象数组去重失效一般是对象类没有重写 equals 和 hashCode,Set 和 Stream distinct 判断重复依靠这两个方法,没有重写会默认按对象地址比较,就算内容一样也判定不是重复元素。
问题 4 java 数组去重之后还能保持原来顺序吗
回答 1 要看选择的实现方案,LinkedHashSet Stream distinct 双重循环实现的 java 数组去重可以保留原顺序,HashSet 和排序相邻比对方案会打乱原有元素顺序,选择方案前要确认业务是否要求保序。
【免责申明】
本文内容为 java 数组去重基础代码思路讲解,不同 JDK 版本 API 表现基本一致,业务开发还要根据元素类型和性能要求选择方案,内容仅作为学习面试参考。


