当前位置: 首页 > 科技观察

Java8中通过Stream对列表进行去重的几种方法

时间:2023-03-15 14:13:54 科技观察

1、Stream的distinct()方法distinct()是Java8中Stream提供的方法,返回一个由流中不同元素组成的流。distinct()使用hashCode()和eqauls()方法来获取不同的元素。因此,需要去重的类必须实现hashCode()和equals()方法。也就是说,我们可以通过重写自定义的hashCode()和equals()方法来实现一些特殊需求的去重。distinct()方法声明如下:Streamdistinct();1.1String列表去重因为String类重写了equals()和hashCode()方法,所以可以成功去重。@TestpublicvoidlistDistinctByStreamDistinct(){//1.对于String列表去重ListstringList=newArrayList(){{add("A");添加(“A”);添加(“乙”);添加(“乙”);添加(“C”);}};out.print("去重之前:");for(Strings:stringList){out.print(s);}out.println();stringList=stringList.stream().distinct().collect(Collectors.toList());out.print("去重后:");for(Strings:stringList){out.print(s);}out.println();}结果如下:去重前:AABBC去重后:ABC1.2实体类列表去重:代码中我们使用了Lombok插件的@Data注解,可以自动覆盖equals()和hashCode()方法。/***定义一个实体类*/@DatapublicclassStudent{privateStringstuNo;私有字符串名称;}@TestpublicvoidlistDistinctByStreamDistinct()throwsJsonProcessingException{ObjectMapperobjectMapper=newObjectMapper();//1.学生列表去重ListstudentList=getStudentList();out.print("去重之前:");out.println(objectMapper.writeValueAsString(studentList));studentList=studentList.stream().distinct().collect(Collectors.toList());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新建一个Listout@TestpublicvoiddistinctByProperty1()throwsJsonProcessingException{//这里的第一种方法是新建一个listwith只有不同的元素根据对象的某个属性实现去重ObjectMapperobjectMapper=newObjectMapper();ListstudentList=getStudentList();out.print("去重之前:");out.println(objectMapper.writeValueAsString(studentList));studentList=studentList.stream().distinct().collect(Collectors.toList());out.print("去重后不同:");out.println(objectMapper.writeValueAsString(studentList));//这里引入两个静态方法,使用TreeSet<>实现获取不同元素的效果//1.importstaticjava.util.stream.Collectors.collectingAndThen;//2.导入静态java.util.stream.Collectors.toCollection;studentList=studentList.stream().collect(collectingAndThen(toCollection(()->newTreeSet<>(Comparator.comparing(Student::getName))),ArrayList::new));out.print("根据名字去重后:");out.println(objectMapper.writeValueAsString(studentList));}结果如下:去重前:[{"stuNo":"001","name":"Tom"},{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]distinctafterdeduplication:[{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]根据名字去重后:[{"stuNo":"001","name":"Tom"}]2.2通过filter()方法,我们先创建一个方法作为Stream.filter()的参数,返回类型为Predicate,原理是判断一个元素是否可以加入代码如下:privatestaticPredicatedistinctByKey(FunctionkeyExtractor){Setseen=ConcurrentHashMap.newKeySet();returnt->seen.add(keyExtractor.apply(t));}用法如下:去重前:[{"stuNo":"001","name":"Tom"},{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]distinctafterdeduplication:[{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]根据名字去重后:[{"stuNo":"001","name":"Tom"}]3.总结上面就是我要的方法分享一下关于列表去重,当然这里就不做更详细的性能分析了,希望以后深入底层重新分析,如有错误,还望大家赐教.