几种列表去重的方法

在这里我来分享几种列表去重的方法,算是一次整理吧,如有纰漏,请不吝赐教。1. Stream 的distinct()方法

distinct()是Java8中 Stream 提供的方法,返回的是由该流中不同元素组成的流。distinct()使用 hashCode() 和 eqauls() 方法来获取不同的元素。因此,需要去重的类必须实现 hashCode() 和 equals() 方法。换句话讲,我们可以通过重写定制的 hashCode() 和 equals() 方法来达到某些特殊需求的去重。

distinct() 方法声明如下:

Streamdistinct();

复制代码1.1对于 String 列表的去重

因为 String 类已经覆写了 equals() 和 hashCode() 方法,所以可以去重成功。

@Testpublic voidlistDistinctByStreamDistinct() {//1. 对于 String 列表去重

List stringList = new ArrayList() {{

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().collect(Collectors.toList());

out.print("去重后:");for(String s : stringList) {

out.print(s);

}

out.println();

}

复制代码

结果如下:

去重前:AABBC

去重后:ABC

复制代码1.2对于实体类列表的去重

注:代码中我们使用了 Lombok 插件的 @Data注解,可自动覆写 equals() 以及 hashCode() 方法。/*** 定义一个实体类*/@Datapublic classStudent {privateString stuNo;privateString name;

}

复制代码

@Testpublic void listDistinctByStreamDistinct() throwsJsonProcessingException {

ObjectMapper objectMapper= newObjectMapper();//1. 对于 Student 列表去重

List studentList =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新建一个列表出来

@Testpublic void distinctByProperty1() throwsJsonProcessingException {//这里第一种方法我们通过新创建一个只有不同元素列表来实现根据对象某个属性去重

ObjectMapper objectMapper = newObjectMapper();

List studentList =getStudentList();

out.print("去重前 :");

out.println(objectMapper.writeValueAsString(studentList));

studentList=studentList.stream().distinct().collect(Collectors.toList());

out.print("distinct去重后:");

out.println(objectMapper.writeValueAsString(studentList));//这里我们引入了两个静态方法,以及通过 TreeSet<> 来达到获取不同元素的效果//1. import static java.util.stream.Collectors.collectingAndThen;//2. import static java.util.stream.Collectors.toCollection;

studentList =studentList.stream().collect(

collectingAndThen(

toCollection(()-> new TreeSet<>(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"}]

distinct去重后:[{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]

根据名字去重后 :[{"stuNo":"001","name":"Tom"}]

复制代码2.2通过 filter() 方法

我们首先创建一个方法作为 Stream.filter() 的参数,其返回类型为 Predicate,原理就是判断一个元素能否加入到 Set 中去,代码如下:private static Predicate distinctByKey(Function super T, ?>keyExtractor) {

Set seen =ConcurrentHashMap.newKeySet();return t ->seen.add(keyExtractor.apply(t));

}

复制代码

使用如下:

@Testpublic void distinctByProperty2() throwsJsonProcessingException {//这里第二种方法我们通过过滤来实现根据对象某个属性去重

ObjectMapper objectMapper = newObjectMapper();

List studentList =getStudentList();

out.print("去重前 :");

out.println(objectMapper.writeValueAsString(studentList));

studentList=studentList.stream().distinct().collect(Collectors.toList());

out.print("distinct去重后:");

out.println(objectMapper.writeValueAsString(studentList));//这里我们将 distinctByKey() 方法作为 filter() 的参数,过滤掉那些不能加入到 set 的元素

studentList =studentList.stream().filter(distinctByKey(Student::getName)).collect(Collectors.toList());

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"}]

复制代码3. 总结

以上便是我要分享的几种关于列表去重的方法,当然这里没有进行更为详尽的性能分析,希望以后会深入底层再重新分析一下。如有纰漏,还望不吝赐教。

代码地址:github

转载于:https://juejin.im/post/5cd6b719f265da03b2044d56

通过stream去重_分享几种 Java8 中通过 Stream 对列表进行去重的方法相关推荐

  1. 【Java8新特性】面试官问我:Java8中创建Stream流有哪几种方式?

    写在前面 先说点题外话:不少读者工作几年后,仍然在使用Java7之前版本的方法,对于Java8版本的新特性,甚至是Java7的新特性几乎没有接触过.真心想对这些读者说:你真的需要了解下Java8甚至以 ...

  2. Java8中的Stream

    Java8 Stream是一个非常好用的工具,结合Lambda表达式,可以非常方便的来操作各种集合. 文章目录 Stream知识图谱 Stream概述 Stream的创建 Stream的使用 遍历/匹 ...

  3. java8中的Stream用法详解

    项目github地址:bitcarmanlee easy-algorithm-interview-and-practice 欢迎大家star,留言,一起学习进步 1.为什么java8中加入Stream ...

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

    点击关注公众号,实用技术文章及时了解 来源:juejin.cn/post/6844903842132262926 在这里我来分享几种列表去重的方法,算是一次整理吧,如有纰漏,请不吝赐教. 1. Str ...

  5. stream distinct去重_再来看看Java的新特性——Stream流

    半年前开始试着使用Java的新特性,给我印象最深的就是Stream流和Optional.其中Stream提高了看法效率,让代码看起来十分清爽. 为什么要使用流? 摘要中已经说明了,为了提高开发效率.流 ...

  6. 如何给html文件夹密码,怎样给文件夹加上密码_分享两种给文件夹设密码的方法...

    现在大家习惯把重要的文件或比较隐私的文件存放在电脑上,出于安全考虑,大家会选择给文件夹设密码.但是问题来了,怎样给文件夹加密码呢?估计大多数的人都还不太清楚该怎么设置吧,别着急,这里小编分享两种给文件 ...

  7. css里面li标签怎么加图片_分享三种给li标签添加图标的方法

    我们在页面布局时,经常会用到li标签,单独使用li标签比较单调,有时候为了页面效果,需要加入图片,那怎么在li标签中添加图片呢?这篇文章就和大家分享三种给li标签添加图标的方法,希望对你有用. 1.使 ...

  8. lambda 对象去重_最火的java8新特性:Lambda 表达式

    主要内容 1. Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 其他新特性 Java 8新特性简介 速度更快 代码更少(增加了新的语法 Lambd ...

  9. 巧用Java8中的Stream,让集合操作6到飞起!!!

    简介 java8也出来好久了,接口默认方法,lambda表达式,函数式接口,Date API等特性还是有必要去了解一下.比如在项目中经常用到集合,遍历集合可以试下lambda表达式,经常还要对集合进行 ...

最新文章

  1. 如何选择合适的损失函数,请看......
  2. TaskManager
  3. 大佬带你详解Python反爬虫措施以及爬虫编写注意事项
  4. python循环最简单的解释_python循环-通往简洁的必经之路
  5. Python学习教程(Python学习路线):Python面试100题(二)
  6. android7.1+msm8937双MIC改为单MIC(晓龙相机录像声音小)
  7. linux测试网页装载时间,使用curl测试web页面响应加载速度
  8. 把JS里面的Date规范输出为“YYYY-MM-DD HH:mm:SS”的字符串
  9. 大数据 -- Hadoop集群环境搭建
  10. Android开发之使用Android studio进行两个项目合并的方法
  11. “iQOO”怎么读?vivo官宣“发音”视频
  12. 江苏一女子给程序员老公买假发,看到其后脑勺后,网友们哭笑不得
  13. Python学习-第三天-面向对象编程基础
  14. 复仇者联盟4预售火爆 一张票在eBay上最高炒至500美元
  15. Access2016学习9
  16. 视频带宽(码流_分辨率_帧率)
  17. C++ sort函数(升序降序排列)
  18. 分页删除后一页数据后,如何自动显示上一页数据
  19. 华为OWS平台和HEC服务浅见
  20. tableau 字段去重_tableau prep学习

热门文章

  1. Win10彻底关闭Antimalware Service Executable占用内存过高问题
  2. Mac目录映射到docker容器ubuntu目录
  3. FFmpeg3.2最新版编译Mediacodec For Android脚本
  4. fprintf fscanf等函数的用法
  5. 细数AVPlayer的那些坑
  6. ios gpuimage输入和得到原始数据
  7. ubuntu常用状态查看命令
  8. 成人教育计算机教育论文,【计算机教育论文】成人计算机教育应把握原则(共3460字)...
  9. ERROR: Could not install Gradle distribution from ‘https://services.gradle.org/distributions/gradle
  10. Android Studio如何允许访问网络资源