本文目录导读:

- 方法一:使用HashSet(推荐,保持顺序)
- 方法二:使用Java 8 Stream API(简洁优雅)
- 方法三:手动实现(不使用集合类)
- 方法四:针对字符串数组去重
- 方法五:对象数组去重(自定义对象)
- 性能对比与选择建议
在Java中实现数组去重有多种方法,我将分享几种常见且实用的实现方式。
使用HashSet(推荐,保持顺序)
import java.util.*;
public class ArrayDeduplication {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 2, 4, 1, 5, 3, 6};
// 方式1:不保持原始顺序
int[] result1 = removeDuplicatesWithSet(arr);
System.out.println("不保持顺序: " + Arrays.toString(result1));
// 方式2:保持原始顺序
int[] result2 = removeDuplicatesWithLinkedHashSet(arr);
System.out.println("保持顺序: " + Arrays.toString(result2));
}
// 方式1:使用HashSet(不保持顺序)
public static int[] removeDuplicatesWithSet(int[] arr) {
Set<Integer> set = new HashSet<>();
for (int num : arr) {
set.add(num);
}
int[] result = new int[set.size()];
int index = 0;
for (int num : set) {
result[index++] = num;
}
return result;
}
// 方式2:使用LinkedHashSet(保持顺序)
public static int[] removeDuplicatesWithLinkedHashSet(int[] arr) {
Set<Integer> set = new LinkedHashSet<>();
for (int num : arr) {
set.add(num);
}
int[] result = new int[set.size()];
int index = 0;
for (int num : set) {
result[index++] = num;
}
return result;
}
}
使用Java 8 Stream API(简洁优雅)
import java.util.*;
import java.util.stream.*;
public class StreamDeduplication {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 2, 4, 1, 5, 3, 6};
// 使用Stream去重
int[] result = Arrays.stream(arr)
.distinct()
.toArray();
System.out.println("去重结果: " + Arrays.toString(result));
}
}
手动实现(不使用集合类)
public class ManualDeduplication {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 2, 4, 1, 5, 3, 6};
int[] result = removeDuplicatesManual(arr);
System.out.println("手动去重: " + Arrays.toString(result));
}
public static int[] removeDuplicatesManual(int[] arr) {
if (arr == null || arr.length == 0) {
return new int[0];
}
// 先排序
Arrays.sort(arr);
// 统计不重复元素个数
int uniqueCount = 1;
for (int i = 1; i < arr.length; i++) {
if (arr[i] != arr[i-1]) {
uniqueCount++;
}
}
// 创建结果数组
int[] result = new int[uniqueCount];
result[0] = arr[0];
int index = 1;
for (int i = 1; i < arr.length; i++) {
if (arr[i] != arr[i-1]) {
result[index++] = arr[i];
}
}
return result;
}
}
针对字符串数组去重
import java.util.*;
public class StringArrayDeduplication {
public static void main(String[] args) {
String[] arr = {"apple", "banana", "apple", "orange", "banana"};
// 方法1:使用Set
Set<String> set = new LinkedHashSet<>(Arrays.asList(arr));
String[] result1 = set.toArray(new String[0]);
System.out.println("字符串去重: " + Arrays.toString(result1));
// 方法2:使用Stream
String[] result2 = Arrays.stream(arr)
.distinct()
.toArray(String[]::new);
System.out.println("Stream去重: " + Arrays.toString(result2));
}
}
对象数组去重(自定义对象)
import java.util.*;
import java.util.stream.*;
class Person {
private int id;
private String name;
private int age;
public Person(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// 重写equals和hashCode方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return id == person.id &&
age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name, age);
}
@Override
public String toString() {
return "Person{id=" + id + ", name='" + name + "', age=" + age + "}";
}
}
public class ObjectArrayDeduplication {
public static void main(String[] args) {
Person[] persons = {
new Person(1, "张三", 20),
new Person(2, "李四", 25),
new Person(1, "张三", 20), // 重复
new Person(3, "王五", 30),
new Person(2, "李四", 25) // 重复
};
// 对象数组去重
Person[] result = Arrays.stream(persons)
.distinct()
.toArray(Person[]::new);
System.out.println("对象去重结果:");
for (Person p : result) {
System.out.println(p);
}
}
}
性能对比与选择建议
| 方法 | 时间复杂度 | 空间复杂度 | 是否保持顺序 | 适用场景 |
|---|---|---|---|---|
| HashSet | O(n) | O(n) | 否 | 一般去重需求 |
| LinkedHashSet | O(n) | O(n) | 是 | 需要保持顺序 |
| Stream API | O(n) | O(n) | 是 | Java 8+项目 |
| 手动实现(排序) | O(n log n) | O(n) | 否(按排序顺序) | 内存受限 |
| 双层循环 | O(n²) | O(1) | 是 | 数据量小 |
推荐使用Stream API方式,它代码简洁、可读性强,而且保持了原始顺序。
如果对性能有极致要求且不需要保持顺序,可以使用HashSet方式;如果需要保持顺序,使用LinkedHashSet。