有兩種方法實現,一種是通過重寫對象的的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<Student> 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<Student> 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 <T> Predicate<T> distinctByField(Function<? super T,?> fieldExtractor){
Map<Object,Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(fieldExtractor.apply(t), Boolean.TRUE) == null;
}
}
運行結果:
去重前:
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的數據。