在 Java 开发中,处理数据时经常会遇到需要删除重复数字的场景,比如从用户输入的数组中提取唯一数值、统计数据集中不重复的元素等。不同场景下,适合的实现方法有所差异,小编将介绍四种常用的 Java 剔除重复数值的方法,包括基于集合、数组遍历、排序去重以及 Stream 流的实现方式,帮助开发者根据实际需求选择合适的方案。
方法一:利用 Set 集合自动去重(最简单高效)
Set 集合是 Java 中的一种无序集合,其核心特性是 “不允许存储重复元素”,因此可以直接利用这一特性实现重复数字的删除。该方法无需手动判断元素是否重复,代码简洁,适合大多数基础去重场景。
实现步骤分为三步:首先将存储数字的数组或列表转换为 Set 集合,Set 会自动过滤掉重复元素;然后根据需求将 Set 集合转回数组或列表;最后获取去重后的结果。以 int 数组为例,具体代码如下:
java取消自动换行复制
若需要保持原始数组的元素顺序,可将HashSet替换为LinkedHashSet,LinkedHashSet会保留元素的插入顺序,其他代码逻辑不变。该方法的时间复杂度约为 O (n)(n 为元素数量),效率较高,但 Set 集合无法直接存储基本数据类型,需使用包装类(如 Integer),不过 Java 的自动装箱 / 拆箱机制会简化这一过程。
方法二:数组遍历手动去重(适合基础场景)
若不希望依赖集合类,可通过数组遍历的方式手动判断并剔除重复元素。该方法需要创建新数组存储唯一元素,通过双重循环对比元素是否重复,适合对集合类不熟悉或需自定义去重逻辑的场景。
实现思路:先创建一个临时列表(或新数组)存储去重后的元素;遍历原始数组,对每个元素,检查它是否已存在于临时列表中;若不存在,则添加到临时列表,若已存在则跳过;最后将临时列表转换为数组。代码示例如下:
java取消自动换行复制
该方法的优点是逻辑直观,无需依赖 Set 集合的特性,缺点是存在双重循环,时间复杂度为 O (n²),当元素数量较多(如超过 1000 个)时,效率会明显下降,因此更适合小规模数据的去重。
方法三:先排序再去重(适合需排序的场景)
若业务中需要对数字进行排序,可先通过排序算法将数组按升序或降序排列,排序后重复元素会相邻排列,再通过一次遍历即可删除重复元素。该方法结合了排序与去重,适合既需去重又需排序的场景。
实现步骤:首先使用Arrays.sort()对原始数组进行排序;然后创建新数组或列表,遍历排序后的数组,仅保留与前一个元素不同的元素(即跳过重复元素)。代码示例如下:
java取消自动换行复制
import java.util.Arrays;
public class RemoveDuplicatesAfterSort {
public static void main(String[] args) {
int[] originalArray = {7, 2, 3, 2, 7, 5, 3, 8};
// 1. 对数组排序(默认升序)
Arrays.sort(originalArray);
// 2. 遍历排序后的数组,去重
// 临时变量存储去重后的元素个数
int uniqueCount = 1;
for (int i = 1; i < originalArray.length; i++) {
// 若当前元素与前一个元素不同,则为唯一元素
if (originalArray[i] != originalArray[uniqueCount - 1]) {
originalArray[uniqueCount] = originalArray[i];
uniqueCount++;
}
}
// 3. 截取数组,获取去重后的结果
int[] uniqueArray = Arrays.copyOf(originalArray, uniqueCount);
// 输出结果:[2, 3, 5, 7, 8](已排序且无重复)
System.out.println(Arrays.toString(uniqueArray));
}
}
该方法的时间复杂度主要取决于排序步骤,Arrays.sort()采用的是双轴快速排序算法,时间复杂度约为 O (n log n),后续遍历去重的时间复杂度为 O (n),整体效率优于手动遍历去重。但缺点是会改变原始数组的顺序(转为排序后的顺序),若需保留原始顺序则不适用。
方法四:使用 Stream 流去重(Java 8 及以上,代码最简洁)
Java 8 引入的 Stream 流提供了便捷的数据处理能力,通过distinct()方法可直接实现元素去重,配合collect()方法还能将结果转换为数组或列表,代码简洁且可读性高,适合 Java 8 及以上版本的开发场景
实现步骤:将数组或集合转换为 Stream 流;调用distinct()方法去重;通过collect()将流转换为目标数据结构(如 List),若需数组则进一步转换。代码示例如下:
j取消自动换行复制
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class RemoveDuplicatesWithStream {
public static void main(String[] args) {
int[] originalArray = {6, 3, 8, 3, 6, 2, 9, 2};
// 1. 数组转Stream流,去重后转为List
List<Integer> uniqueList = Arrays.stream(originalArray)
.boxed() // 基本类型转包装类
.distinct() // 去重
.collect(Collectors.toList());
// 2. 若需数组,可从List转换
int[] uniqueArray = uniqueList.stream()
.mapToInt(Integer::intValue)
.toArray();
// 输出结果:[6, 3, 8, 2, 9](Stream流默认顺序与原始数组一致)
System.out.println(Arrays.toString(uniqueArray));
}
}
该方法的优点是代码简洁,一行链式调用即可完成去重,且distinct()方法内部通过LinkedHashSet实现,能保留元素的原始顺序,时间复杂度约为 O (n)。但需注意,该方法依赖 Java 8 及以上版本,且对于大规模数据,Stream 流的性能与 Set 集合相近,适合追求代码简洁性的场景。
四种方法各有优缺点,实际开发中需根据场景选择:若需简单高效且不依赖版本,优先选择 Set 集合去重;若需保留原始顺序且使用 Java 8+,推荐 Stream 流;若需同时排序,可采用先排序再去重的方式;若对集合类不熟悉或数据量小,手动遍历去重更易理解。无论选择哪种方法,核心思路都是通过 “判断元素唯一性” 实现去重,开发者可根据数据规模、版本要求及顺序需求灵活选择。