java8之stream集合去重的⽅法
1. Stream 的distinct()⽅法
distinct()是Java 8 中 Stream 提供的⽅法,返回的是由该流中不同元素组成的流。distinct()使⽤ hashCode() 和 eqauls() ⽅法来获取不同的元素。因此,需要去重的类必须实现 hashCode() 和 equals() ⽅法。换句话讲,我们可以通过重写定制的 hashCode() 和equals() ⽅法来达到某些特殊需求的去重。
distinct() ⽅法声明如下:
Stream<T>distinct();
1.1 对于 String 列表的去重
因为 String 类已经覆写了 equals() 和 hashCode() ⽅法,所以可以去重成功。
@Test
public void listDistinctByStreamDistinct(){
// 1. 对于 String 列表去重
List<String> stringList =new ArrayList<String>(){{
add("A");
add("A");
add("B");
add("B");
add("C");
}};
out.print("去重前:");
for(String s : stringList){
out.print(s);
}
out.println();
stringList = stringList.stream().distinct().List());
out.print("去重后:");
for(String s : stringList){
out.print(s);
}
out.println();
}
结果如下:
去重前:AABBC
去重后:ABC
1.2 对于实体类列表的去重
注:代码中我们使⽤了 Lombok 插件的 @Data注解,可⾃动覆写 equals() 以及 hashCode() ⽅法。
/**
* 定义⼀个实体类
*/
@Data
public class Student {
private String stuNo;
private String name;
}
@Test
public void listDistinctByStreamDistinct()throws JsonProcessingException {
ObjectMapper objectMapper =new ObjectMapper();
// 1. 对于 Student 列表去重
List<Student> studentList =getStudentList();
java stream
out.print("去重前:");
out.println(objectMapper.writeValueAsString(studentList));
studentList = studentList.stream().distinct().List());
out.print("去重后:");
out.println(objectMapper.writeValueAsString(studentList));
}
结果如下:
去重前:[{"stuNo":"001","name":"Tom"},{"stuNo":"002","name":"Mike"},{"stuNo":"001","name":"Tom"}]
去重后:[{"stuNo":"001","name":"Tom"},{"stuNo":"002","name":"Mike"}]
2. 根据 List 中 Object 某个属性去重
2.1 新建⼀个列表出来
@Test
public void distinctByProperty1()throws JsonProcessingException {
// 这⾥第⼀种⽅法我们通过新创建⼀个只有不同元素列表来实现根据对象某个属性去重
ObjectMapper objectMapper =new ObjectMapper();
List<Student> studentList =getStudentList();
out.print("去重前        :");
out.println(objectMapper.writeValueAsString(studentList));
studentList = studentList.stream().distinct().List());
out.print("distinct去重后:");
out.println(objectMapper.writeValueAsString(studentList));
// 这⾥我们引⼊了两个静态⽅法,以及通过 TreeSet<> 来达到获取不同元素的效果
// 1. import static java.util.llectingAndThen;
// 2. import static java.util.Collection;
studentList = studentList.stream().collect(
collectingAndThen(
toCollection(()->new TreeSet<>(Comparatorparing(Student::getName))), ArrayList::new)
);
out.print("根据名字去重后 :");
out.println(objectMapper.writeValueAsString(studentList));
}
结果如下:
去重前        :[{"stuNo":"001","name":"Tom"},{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]
distinct去重后:[{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]
根据名字去重后 :[{"stuNo":"001","name":"Tom"}]
2.2 通过 filter() ⽅法
我们⾸先创建⼀个⽅法作为 Stream.filter() 的参数,其返回类型为 Predicate,原理就是判断⼀个元素能否加⼊到 Set 中去,代码如下:
private static<T> Predicate<T>distinctByKey(Function<?super T,?> keyExtractor){
Set<Object> seen = wKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
使⽤如下:
@Test
public void distinctByProperty2()throws JsonProcessingException {
// 这⾥第⼆种⽅法我们通过过滤来实现根据对象某个属性去重
ObjectMapper objectMapper =new ObjectMapper();
List<Student> studentList =getStudentList();
out.print("去重前        :");
out.println(objectMapper.writeValueAsString(studentList));
studentList = studentList.stream().distinct().List());
out.print("distinct去重后:");
out.println(objectMapper.writeValueAsString(studentList));
// 这⾥我们将 distinctByKey() ⽅法作为 filter() 的参数,过滤掉那些不能加⼊到 set 的元素
studentList = studentList.stream().filter(distinctByKey(Student::getName)).List());    out.print("根据名字去重后 :");
out.println(objectMapper.writeValueAsString(studentList));
}
结果如下:
去重前        :[{"stuNo":"001","name":"Tom"},{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}] distinct去重后:[{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]
根据名字去重后 :[{"stuNo":"001","name":"Tom"}]

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。