使用Java8的Stream的distinct方法去重,我们的对象需要实现hashcode()和equals()方法。
把学生类修改后如下:
public class Student {
private Long id;
private String name;
private int age;
private Double height;
public Student(Long id, String name, int age, Double height) {
this.id = id;
this.name = name;
this.age = age;
this.height = height;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(id, student.id) &&
Objects.equals(name, student.name) &&
Objects.equals(height, student.height);
}
@Override
public int hashCode() {
return Objects.hash(id, name, age, height);
}
}
测试例子:
import com.top.test.dto.Student;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class ListStreamDistinctTest {
public static void main(String[] args) {
// 一个集合中放入4个学生对象
List list = new ArrayList<>();
list.add(new Student(10002L, "ZhangSan", 18, 175.2));
list.add(new Student(10001L, "LiSi", 19, 175.2));
list.add(new Student(10004L, "Peter", 19, 170.8));
list.add(new Student(10004L, "Peter", 19, 170.8));
// 按整个个对象去重
System.out.println("整个对象去重:");
list.stream().distinct()
.forEach(System.out::println);
// 指定某个字段去重
System.out.println("指定age属性去重(方法一):");
list.stream().filter(distinctByKey1(s -> s.getAge()))
.forEach(System.out::println);
// 方法二(用循环)
System.out.println("指定age属性去重(方法二):");
TreeSet students = new TreeSet<>(Comparator.comparing(s -> s.getAge()));
for (Student student : list) {
students.add(student);
}
new ArrayList<>(students)
.forEach(System.out::println);
// 方法三:(是方法二的变形),此方法来源于:https://blog.csdn.net/qq_28988969/article/details/81119587
System.out.println("指定age属性去重(方法三):");
list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(s -> s.getAge()))), ArrayList::new))
.forEach(System.out::println);
}
// 次方法来源于:https://blog.csdn.net/haiyoung/article/details/80934467
static Predicate distinctByKey1(Function super T, ?> keyExtractor) {
Map
执行结果:
整个对象去重:
Student{id=10002, name='ZhangSan', age=18, height=175.2}
Student{id=10001, name='LiSi', age=19, height=175.2}
Student{id=10004, name='Peter', age=19, height=170.8}
指定age属性去重(方法一):
Student{id=10002, name='ZhangSan', age=18, height=175.2}
Student{id=10001, name='LiSi', age=19, height=175.2}
指定age属性去重(方法二):
Student{id=10002, name='ZhangSan', age=18, height=175.2}
Student{id=10001, name='LiSi', age=19, height=175.2}
指定age属性去重(方法三):
Student{id=10002, name='ZhangSan', age=18, height=175.2}
Student{id=10001, name='LiSi', age=19, height=175.2}
Lambda表达式和函数式接口看不懂的,可以参考之前的文章:
Java8 Lambda表达式 和 函数式编程 原理详解
个人微信公众号:“Java尖子生”,阅读更多干货。
关注公众号,领取学习、面试资料。加技术讨论群。
阅读更多我的相关内容
Java8 Lambda表达式 和 函数式编程 原理详解
Java8方法引用,示例讲解
Java8-默认方法和默认静态方法
Java8-Stream流操作List排序(完整实例讲解)