Java对象List根据ID去重
- 一、前言
-
- [1. 使用HashSet去重](#1. 使用HashSet去重)
- [2. 使用Stream API去重](#2. 使用Stream API去重)
- [3. 使用HashMap去重](#3. 使用HashMap去重)
- [4. 使用TreeSet去重并保持顺序](#4. 使用TreeSet去重并保持顺序)
- [5. 使用LinkedHashMap确保插入顺序](#5. 使用LinkedHashMap确保插入顺序)
一、前言
在Java中处理大数据时,常常会遇到需要去重的情况。假设我们有一个对象数组,其中对象具有一个ID字段,我们希望将ID相同的对象去重,保留一个对象。下面将介绍几种实现这种去重操作的方法,包括使用集合、流(Streams)以及Map数据结构。
1. 使用HashSet去重
HashSet利用哈希表的特性,可以有效地对元素进行去重。此方法的时间复杂度接近O(n)。
java
import java.util.*;
class MyObject {
private int id;
private String data;
public MyObject(int id, String data) {
this.id = id;
this.data = data;
}
public int getId() {
return id;
}
// Equals and hashCode should be based on the ID for correct behavior in HashSet
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyObject myObject = (MyObject) o;
return id == myObject.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return "MyObject{id=" + id + ", data='" + data + "'}";
}
}
public class Main {
public static void main(String[] args) {
List<MyObject> list = Arrays.asList(
new MyObject(1, "data1"),
new MyObject(2, "data2"),
new MyObject(1, "data3"),
new MyObject(3, "data4")
);
Set<MyObject> set = new HashSet<>(list);
List<MyObject> resultList = new ArrayList<>(set);
System.out.println(resultList);
}
}
2. 使用Stream API去重
Java 8引入了Stream API,可以通过distinct()
方法直接对流中的元素进行去重。
java
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<MyObject> list = Arrays.asList(
new MyObject(1, "data1"),
new MyObject(2, "data2"),
new MyObject(1, "data3"),
new MyObject(3, "data4")
);
List<MyObject> resultList = list.stream()
.filter(distinctByKey(MyObject::getId))
.collect(Collectors.toList());
System.out.println(resultList);
}
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
3. 使用HashMap去重
利用HashMap的键值对特性,我们可以通过ID作为键来去重,只保留最后一个出现的对象。
java
import java.util.*;
public class Main {
public static void main(String[] args) {
List<MyObject> list = Arrays.asList(
new MyObject(1, "data1"),
new MyObject(2, "data2"),
new MyObject(1, "data3"),
new MyObject(3, "data4")
);
Map<Integer, MyObject> map = new HashMap<>();
for (MyObject obj : list) {
map.put(obj.getId(), obj);
}
List<MyObject> resultList = new ArrayList<>(map.values());
System.out.println(resultList);
}
}
4. 使用TreeSet去重并保持顺序
使用TreeSet可以实现去重并按自然顺序或指定顺序(通过Comparator)排序。
java
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<MyObject> list = Arrays.asList(
new MyObject(1, "data1"),
new MyObject(2, "data2"),
new MyObject(1, "data3"),
new MyObject(3, "data4")
);
TreeSet<MyObject> set = list.stream()
.collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparingInt(MyObject::getId))));
List<MyObject> resultList = new ArrayList<>(set);
System.out.println(resultList);
}
}
5. 使用LinkedHashMap确保插入顺序
LinkedHashMap不仅能去重,还能保持插入顺序。
java
import java.util.*;
public class Main {
public static void main(String[] args) {
List<MyObject> list = Arrays.asList(
new MyObject(1, "data1"),
new MyObject(2, "data2"),
new MyObject(1, "data3"),
new MyObject(3, "data4")
);
Map<Integer, MyObject> map = new LinkedHashMap<>();
for (MyObject obj : list) {
map.putIfAbsent(obj.getId(), obj);
}
List<MyObject> resultList = new ArrayList<>(map.values());
System.out.println(resultList);
}
}
以上是几种不同的方法来实现对象数组中根据ID去重的操作。这些方法各有优劣,具体选择取决于你的实际需求和数据特点。