有两种方法实现,一种是通过重写对象的的equals()和hashcode(),再使用distinct,distinct就是通过equals来去重的,下面看一个简单例子。
package com.test.demo;
import lombok.Data;
/**
* @description:
* @author:
* @create: 2019-11-28 17:08
**/
@Data
public class Student {
private String name;
private int age;
}
这里我使用的lombok的注解@Data,会自动帮我们重写equals和hashcode,toString
package com.test.demo;
import java.util.ArrayList;
import java.util.List;
/**
* @description:
* @author:
* @create: 2019-11-28 17:10
**/
public class DistinctByEquals {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setName("小明");
stu1.setAge(20);
Student stu2 = new Student();
stu2.setName("小明");
stu2.setAge(20);
Student stu3 = new Student();
stu3.setName("小红");
stu3.setAge(18);
List students = new ArrayList();
students.add(stu1);
students.add(stu2);
students.add(stu3);
System.out.println("去重前:");
students.stream().forEach(x->System.out.println(x.toString()));
System.out.println("去重后");
students.stream().distinct().forEach(x->System.out.println(x.toString()));
}
}
运行结果:
去重前:
Student(name=小明, age=20)
Student(name=小明, age=20)
Student(name=小红, age=18)
去重后
Student(name=小明, age=20)
Student(name=小红, age=18)
Process finished with exit code 0
可以看到,相同对象已经被去掉了。
第二种方法,不需要重写equals和hashcode,我们可以通过自定义filter的过滤规则来实现,这里我们通过name属性来去重,
代码如下
package com.test.demo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* @description:
* @author:
* @create: 2019-11-28 17:10
**/
public class DistinctByEquals {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setName("小华");
stu1.setAge(22);
Student stu2 = new Student();
stu2.setName("小华");
stu2.setAge(25);
Student stu3 = new Student();
stu3.setName("小李");
stu3.setAge(19);
List students = new ArrayList();
students.add(stu1);
students.add(stu2);
students.add(stu3);
System.out.println("去重前:");
students.stream().forEach(x->System.out.println(x.toString()));
System.out.println("去重后");
students.stream().filter(distinctByField(student -> student.getName())).forEach(x->System.out.println(x.toString()));
}
static Predicate distinctByField(Function super T,?> fieldExtractor){
Map
运行结果:
去重前:
Student(name=小华, age=22)
Student(name=小华, age=25)
Student(name=小李, age=19)
去重后
Student(name=小华, age=22)
Student(name=小李, age=19)
Process finished with exit code 0
这里主要使用了lambda中的函数式接口,简单来说就是替换了我们原来的匿名类写法,有兴趣的同学可以下去研究研究,这里不多叙述,关于putIfAbsent,该方法作用是 ,如果key不存在或者key已存在但是值为null,就put进去。put进去时返回null,不put进去时返回原值。所以这里就是通过判断返回值是否等于null来判断是否过滤,如果等于null,说明该对象的不重复,返回true,而filter恰好会留下表达式为true的数据。