项目场景:
java stream distinct根据list某个字段去重,普通List简单去重:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class TestMain {
public static void main(String[] args) {
List<String> names = Arrays.asList("张三", "李四", "王五", "张三", "李四");
// 使用Stream的distinct()方法进行去重操作
List<String> distinctNames = names.stream().distinct().collect(Collectors.toList());
System.out.println("原始列表:" + names);
System.out.println("去重后的列表:" + distinctNames);
}
}
很显然这种满足不了需求,我们List里的是实体对象,这里的是字符串。
前提基础:
import lombok.Data;
@Data
public class Student {
public Student(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
private Integer id;
private String name;
private Integer age;
}
解决方案:
一、Stream流 + TreeSet(推荐)
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;
public class TestMain {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student(1, "张三", 13));
list.add(new Student(2, "李四", 14));
list.add(new Student(3, "张三", 15));
list.add(new Student(4, "王五", 16));
list.add(new Student(5, "李四", 17));
List<Student> distinctList = list.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList<Student>::new)
);
System.out.println(distinctList);
}
}
二、Stream流 + toMap
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class TestMain {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student(1, "张三", 13));
list.add(new Student(2, "李四", 14));
list.add(new Student(3, "张三", 15));
list.add(new Student(4, "王五", 16));
list.add(new Student(5, "李四", 17));
List<Student> distinctList = list.stream()
.collect(Collectors.toMap(Student::getName, Function.identity(), (p1, p2) -> p1))
.values()
.stream()
.collect(Collectors.toList());
System.out.println(distinctList);
}
}
三、重写equals和hashCode
Student类在原来的基础上,重写equals和hashCode,根据学生的name去重
import java.util.Objects;
import lombok.Data;
@Data
public class Student {
public Student(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
private Integer id;
private String name;
private Integer age;
// 重写 equals 和 hashCode 方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class TestMain {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student(1, "张三", 13));
list.add(new Student(2, "李四", 14));
list.add(new Student(3, "张三", 15));
list.add(new Student(4, "王五", 16));
list.add(new Student(5, "李四", 17));
List<Student> distinctList = list.stream().distinct().collect(Collectors.toList());
System.out.println(distinctList);
}
}