本文目录导读:

在Java中使用Stream进行数据去重非常方便,主要通过distinct()方法或结合collect(Collectors.toCollection(...))实现,以下是几种常见场景的完整案例:
基础类型数据去重
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class BasicDistinctExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 4, 1, 5, 3);
// 使用distinct()去重
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
System.out.println("原始数据: " + numbers);
System.out.println("去重后: " + distinctNumbers);
// 输出: [1, 2, 3, 4, 5]
}
}
字符串去重(不区分大小写)
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StringDistinctExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("Apple", "banana", "apple", "Banana", "orange");
// 不区分大小写去重
List<String> distinctWords = words.stream()
.map(String::toLowerCase) // 统一转小写
.distinct()
.collect(Collectors.toList());
System.out.println("原始数据: " + words);
System.out.println("不区分大小写去重后: " + distinctWords);
// 输出: [apple, banana, orange]
}
}
对象去重 - 按指定字段
import java.util.*;
import java.util.stream.Collectors;
// 学生类
class Student {
private int id;
private String name;
private int age;
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() { return id; }
public String getName() { return name; }
public int getAge() { return age; }
@Override
public String toString() {
return "Student{id=" + id + ", name='" + name + "', age=" + age + "}";
}
}
public class ObjectDistinctExample {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student(1, "Alice", 20),
new Student(2, "Bob", 22),
new Student(1, "Alice", 20), // 重复
new Student(3, "Charlie", 21),
new Student(2, "Bob", 23) // id重复但年龄不同
);
// 方案1:按id去重(使用TreeSet)
List<Student> distinctById = students.stream()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(() ->
new TreeSet<>(Comparator.comparingInt(Student::getId))
),
ArrayList::new
));
System.out.println("按id去重:");
distinctById.forEach(System.out::println);
// 输出两个学生:id=1和id=2(保留第一次出现的)
// 方案2:按姓名去重(使用toMap)
List<Student> distinctByName = students.stream()
.collect(Collectors.toMap(
Student::getName, // 键提取
student -> student, // 值提取
(existing, replacement) -> existing // 冲突处理:保留第一个
))
.values()
.stream()
.collect(Collectors.toList());
System.out.println("\n按姓名去重:");
distinctByName.forEach(System.out::println);
}
}
多字段组合去重
import java.util.*;
import java.util.stream.Collectors;
public class MultipleFieldDistinctExample {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student(1, "Alice", 20),
new Student(2, "Bob", 22),
new Student(1, "Alice", 20), // 完全重复
new Student(1, "Bob", 22) // id和name重复
);
// 按id+name组合去重
List<Student> distinctByMultipleFields = students.stream()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(() ->
new TreeSet<>(Comparator.comparing(
(Student s) -> s.getId() + "-" + s.getName()
))
),
ArrayList::new
));
System.out.println("按id+name组合去重:");
distinctByMultipleFields.forEach(System.out::println);
// 输出: [Student{id=1, name='Alice', age=20}, Student{id=2, name='Bob', age=22}]
}
}
自定义去重(保留最新数据)
import java.util.*;
import java.util.stream.Collectors;
public class CustomDistinctExample {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student(1, "Alice", 20),
new Student(2, "Bob", 22),
new Student(1, "Alice", 21), // id相同但年龄更新
new Student(3, "Charlie", 21)
);
// 按id去重,保留年龄最大的(即最新数据)
List<Student> distinctWithMaxAge = students.stream()
.collect(Collectors.toMap(
Student::getId,
student -> student,
(old, newStudent) -> old.getAge() >= newStudent.getAge() ? old : newStudent
))
.values()
.stream()
.collect(Collectors.toList());
System.out.println("按id去重(保留年龄最大的):");
distinctWithMaxAge.forEach(System.out::println);
// 输出: [Student{id=1, name='Alice', age=21}, Student{id=2, name='Bob', age=22}, ...]
}
}
处理null值的去重
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class NullSafeDistinctExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", null, "banana", "apple", null, "orange");
// 去重并过滤null
List<String> result = words.stream()
.filter(Objects::nonNull) // 先过滤null
.distinct()
.collect(Collectors.toList());
System.out.println("过滤null并去重: " + result);
// 输出: [apple, banana, orange]
// 如果要保留一个null
List<String> withNull = words.stream()
.distinct()
.collect(Collectors.toList());
System.out.println("含null的去重: " + withNull);
// 输出: [apple, null, banana, orange]
}
}
常用去重方法总结
| 方法 | 适用场景 | 代码示例 |
|---|---|---|
distinct() |
基础类型、对象(需重写equals/hashCode) | list.stream().distinct() |
toCollection(TreeSet) |
按指定字段去重 | Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(对象::get字段))) |
toMap() |
复杂去重逻辑(保留最新、保留第一个等) | Collectors.toMap(键提取, 值提取, 冲突处理) |
最佳实践建议:
- 简单类型去重用
distinct() - 对象去重用
TreeSet或toMap方法 - 需要复杂逻辑(如保留最新)用
toMap重载方法
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播