在Java中,List
集合是常用的数据结构之一。在实际开发中,我们经常需要对List
集合进行去重操作,特别是按某个属性进行去重。本文将详细介绍几种在Java中对List
集合对象去重及按属性去重的方法,并提供一些实用的示例代码。
🧑 博主简介:
现任阿里巴巴嵌入式技术专家,15年工作经验,深耕嵌入式+人工智能领域,精通嵌入式领域开发、技术管理、简历招聘面试。CSDN优质创作者,提供产品测评、学习辅导、简历面试辅导、毕设辅导、项目开发、C/C++/Java/Python/Linux/AI等方面的服务,如有需要请站内私信或者联系任意文章底部的的VX名片(ID:gylzbk
)
💬 博主粉丝群介绍:① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。③ 群内也有职场精英,大厂大佬,可交流技术、面试、找工作的经验。④ 进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬。⑤ 进群赠送CSDN评论防封脚本,送真活跃粉丝,助你提升文章热度。有兴趣的加文末联系方式,备注自己的CSDN昵称,拉你进群,互相学习共同进步。
【Java】List集合对象去重及按属性去重的多种方法
- 1. 使用 `Set` 进行去重
- 2. 使用 `LinkedHashSet` 保持顺序去重
- 3. 使用 `Stream` API 进行去重
- 4. 按属性去重
- 5. 使用 `Comparator` 和 `TreeSet` 按属性去重
- 6. 使用 `LinkedHashMap` 按属性去重
- 7. 使用 `Collectors.collectingAndThen` 和 `toCollection`
- 8. 使用 `Guava` 库的 `Sets.newLinkedHashSet`
- 9. 使用 `Apache Commons Collections` 的 `CollectionUtils`
- 10. 使用 `Map` 的 `computeIfAbsent` 方法
- 11. 使用 `Collectors.groupingBy` 和 `Collectors.reducing` 方法
- 12. 使用第三方库 `StreamEx`
- 总结
1. 使用 Set
进行去重
Set
是一种不允许重复元素的集合,可以利用它的这一特性对 List
进行去重。
1.1 使用 HashSet
进行去重
示例代码:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ListDeduplication {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("apple");
list.add("orange");
Set<String> set = new HashSet<>(list);
List<String> deduplicatedList = new ArrayList<>(set);
System.out.println(deduplicatedList); // 输出: [banana, orange, apple]
}
}
2. 使用 LinkedHashSet
保持顺序去重
LinkedHashSet
是 HashSet
的子类,具有 HashSet
的去重特性,同时保留元素的插入顺序。
示例代码:
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class ListDeduplication {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("apple");
list.add("orange");
Set<String> set = new LinkedHashSet<>(list);
List<String> deduplicatedList = new ArrayList<>(set);
System.out.println(deduplicatedList); // 输出: [apple, banana, orange]
}
}
3. 使用 Stream
API 进行去重
Java 8 引入了 Stream
API,使得去重操作更加简洁。
示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ListDeduplication {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("apple");
list.add("orange");
List<String> deduplicatedList = list.stream().distinct().collect(Collectors.toList());
System.out.println(deduplicatedList); // 输出: [apple, banana, orange]
}
}
4. 按属性去重
对于对象集合,可以按某个属性进行去重。
4.1 使用 HashSet
和 Stream
API 按属性去重
假设有一个包含 Person
对象的 List
,按 name
属性进行去重。
示例代码:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
Set<String> seenNames = new HashSet<>();
List<Person> deduplicatedList = list.stream()
.filter(person -> seenNames.add(person.name))
.collect(Collectors.toList());
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
4.2 使用 Collectors.toMap
按属性去重
示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
Map<String, Person> deduplicatedMap = list.stream()
.collect(Collectors.toMap(person -> person.name, person -> person, (existing, replacement) -> existing));
List<Person> deduplicatedList = new ArrayList<>(deduplicatedMap.values());
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
5. 使用 Comparator
和 TreeSet
按属性去重
TreeSet
是一个有序的集合,可以通过自定义 Comparator
来实现按属性去重。
示例代码:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
Set<Person> deduplicatedSet = new TreeSet<>(Comparator.comparing(person -> person.name));
deduplicatedSet.addAll(list);
List<Person> deduplicatedList = new ArrayList<>(deduplicatedSet);
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
6. 使用 LinkedHashMap
按属性去重
LinkedHashMap
是一个有序的映射,可以通过 key
来实现按属性去重,并保持插入顺序。
示例代码:
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
Map<String, Person> deduplicatedMap = new LinkedHashMap<>();
for (Person person : list) {
deduplicatedMap.putIfAbsent(person.name, person);
}
List<Person> deduplicatedList = new ArrayList<>(deduplicatedMap.values());
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
7. 使用 Collectors.collectingAndThen
和 toCollection
结合 Collectors.collectingAndThen
和 toCollection
方法,可以在流操作中自定义集合的类型。
示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
List<Person> deduplicatedList = list.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(person -> person.name, person -> person, (existing, replacement) -> existing),
map -> new ArrayList<>(map.values())
));
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
8. 使用 Guava
库的 Sets.newLinkedHashSet
Google 的 Guava 库提供了丰富的集合工具,可以使用 Sets.newLinkedHashSet
保持顺序去重。
示例代码:
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
Set<Person> deduplicatedSet = Sets.newLinkedHashSet(list);
List<Person> deduplicatedList = new ArrayList<>(deduplicatedSet);
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
9. 使用 Apache Commons Collections
的 CollectionUtils
Apache Commons Collections 提供了丰富的集合工具,可以使用 CollectionUtils
进行去重。
示例代码:
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
Collection<Person> deduplicatedCollection = CollectionUtils.collect(
new LinkedHashSet<>(list),
new Transformer<Person, Person>() {
public Person transform(Person person) {
return person;
}
}
);
List<Person> deduplicatedList = new ArrayList<>(deduplicatedCollection);
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
10. 使用 Map
的 computeIfAbsent
方法
通过 Map
的 computeIfAbsent
方法,可以在构建过程中去重。
示例代码:
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
Map<String, Person> deduplicatedMap = new LinkedHashMap<>();
for (Person person : list) {
deduplicatedMap.computeIfAbsent(person.name, k -> person);
}
List<Person> deduplicatedList = new ArrayList<>(deduplicatedMap.values());
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
11. 使用 Collectors.groupingBy
和 Collectors.reducing
方法
通过 Collectors.groupingBy
和 Collectors.reducing
方法,可以对对象集合按属性去重并进行聚合操作。
示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
Map<String, Person> deduplicatedMap = list.stream()
.collect(Collectors.groupingBy(
person -> person.name,
Collectors.reducing((p1, p2) -> p1)
))
.entrySet()
.stream()
.filter(entry -> entry.getValue().isPresent())
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().get()));
List<Person> deduplicatedList = new ArrayList<>(deduplicatedMap.values());
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
12. 使用第三方库 StreamEx
StreamEx
是一个增强版的 Java 8 Stream
API,通过 distinct
方法可以方便地按属性去重。
示例代码:
import one.util.streamex.StreamEx;
import java.util.ArrayList;
import java.util.List;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ListDeduplication {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 30));
list.add(new Person("Bob", 25));
list.add(new Person("Alice", 35));
list.add(new Person("Charlie", 40));
List<Person> deduplicatedList = StreamEx.of(list)
.distinct(Person::getName)
.toList();
System.out.println(deduplicatedList);
// 输出: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=40}]
}
}
总结
通过以上示例,我们展示了在 Java 中对 List
集合对象进行去重及按属性去重的多种方法,包括使用 Set
、Stream
API、TreeSet
、LinkedHashMap
、Guava
、Apache Commons Collections
、Map
的 computeIfAbsent
方法、Collectors.groupingBy
和 Collectors.reducing
方法以及第三方库 StreamEx
等。这些方法各有特点,可以根据具体需求选择合适的方法进行去重操作。