码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 分享几种 Java8 中通过 Stream 对列表进行去重的方法


    几种列表去重的方法

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

    1. Stream 的distinct()方法

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

    distinct() 方法声明如下:

    1. Stream distinct();
    2. 复制代码

    1.1 对于 String 列表的去重

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

    1. @Test
    2. public void listDistinctByStreamDistinct() {
    3. // 1. 对于 String 列表去重
    4. List<String> stringList = new ArrayList<String>() {{
    5. add("A");
    6. add("A");
    7. add("B");
    8. add("B");
    9. add("C");
    10. }};
    11. out.print("去重前:");
    12. for (String s : stringList) {
    13. out.print(s);
    14. }
    15. out.println();
    16. stringList = stringList.stream().distinct().collect(Collectors.toList());
    17. out.print("去重后:");
    18. for (String s : stringList) {
    19. out.print(s);
    20. }
    21. out.println();
    22. }
    23. 复制代码

    结果如下:

    1. 去重前:AABBC
    2. 去重后:ABC
    3. 复制代码

    1.2 对于实体类列表的去重

    注:代码中我们使用了 Lombok 插件的 @Data注解,可自动覆写 equals() 以及 hashCode() 方法。

    1. /**
    2. * 定义一个实体类
    3. */
    4. @Data
    5. public class Student {
    6. private String stuNo;
    7. private String name;
    8. }
    9. 复制代码
    1. @Test
    2. public void listDistinctByStreamDistinct() throws JsonProcessingException {
    3. ObjectMapper objectMapper = new ObjectMapper();
    4. // 1. 对于 Student 列表去重
    5. List studentList = getStudentList();
    6. out.print("去重前:");
    7. out.println(objectMapper.writeValueAsString(studentList));
    8. studentList = studentList.stream().distinct().collect(Collectors.toList());
    9. out.print("去重后:");
    10. out.println(objectMapper.writeValueAsString(studentList));
    11. }
    12. 复制代码

    结果如下:

    1. 去重前:[{"stuNo":"001","name":"Tom"},{"stuNo":"002","name":"Mike"},{"stuNo":"001","name":"Tom"}]
    2. 去重后:[{"stuNo":"001","name":"Tom"},{"stuNo":"002","name":"Mike"}]
    3. 复制代码

    2. 根据 List 中 Object 某个属性去重

    2.1 新建一个列表出来

    1. @Test
    2. public void distinctByProperty1() throws JsonProcessingException {
    3. // 这里第一种方法我们通过新创建一个只有不同元素列表来实现根据对象某个属性去重
    4. ObjectMapper objectMapper = new ObjectMapper();
    5. List<Student> studentList = getStudentList();
    6. out.print("去重前 :");
    7. out.println(objectMapper.writeValueAsString(studentList));
    8. studentList = studentList.stream().distinct().collect(Collectors.toList());
    9. out.print("distinct去重后:");
    10. out.println(objectMapper.writeValueAsString(studentList));
    11. // 这里我们引入了两个静态方法,以及通过 TreeSet<> 来达到获取不同元素的效果
    12. // 1. import static java.util.stream.Collectors.collectingAndThen;
    13. // 2. import static java.util.stream.Collectors.toCollection;
    14. studentList = studentList.stream().collect(
    15. collectingAndThen(
    16. toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList::new)
    17. );
    18. out.print("根据名字去重后 :");
    19. out.println(objectMapper.writeValueAsString(studentList));
    20. }
    21. 复制代码

    结果如下:

    1. 去重前 :[{"stuNo":"001","name":"Tom"},{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]
    2. distinct去重后:[{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]
    3. 根据名字去重后 :[{"stuNo":"001","name":"Tom"}]
    4. 复制代码

    2.2 通过 filter() 方法

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

    1. private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    2. Set<Object> seen = ConcurrentHashMap.newKeySet();
    3. return t -> seen.add(keyExtractor.apply(t));
    4. }
    5. 复制代码

    使用如下:

    1. @Test
    2. public void distinctByProperty2() throws JsonProcessingException {
    3. // 这里第二种方法我们通过过滤来实现根据对象某个属性去重
    4. ObjectMapper objectMapper = new ObjectMapper();
    5. List<Student> studentList = getStudentList();
    6. out.print("去重前 :");
    7. out.println(objectMapper.writeValueAsString(studentList));
    8. studentList = studentList.stream().distinct().collect(Collectors.toList());
    9. out.print("distinct去重后:");
    10. out.println(objectMapper.writeValueAsString(studentList));
    11. // 这里我们将 distinctByKey() 方法作为 filter() 的参数,过滤掉那些不能加入到 set 的元素
    12. studentList = studentList.stream().filter(distinctByKey(Student::getName)).collect(Collectors.toList());
    13. out.print("根据名字去重后 :");
    14. out.println(objectMapper.writeValueAsString(studentList));
    15. }
    16. 复制代码

    结果如下:

    1. 去重前 :[{"stuNo":"001","name":"Tom"},{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]
    2. distinct去重后:[{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]
    3. 根据名字去重后 :[{"stuNo":"001","name":"Tom"}]
    4. 复制代码

    3. 总结

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

  • 相关阅读:
    泰勒公式专题 拉格朗日余项与佩亚诺余项,麦克劳林公式
    新建Maui工程运行到IiOS物理设备提示 Could not find any available provisioning profiles for iOS 处理办法
    JS事件处理机制/微任务和宏任务
    别再盯着40系,这些才是目前性价比最高的显卡
    Redis文件事件模型
    计算机毕业设计ssm基于web的暗香小店系统的设计与实现80041系统+程序+源码+lw+远程部署
    Java SPI的本质
    python之正则表达式【简化版】
    vue3第三节(v-model 执行原理)
    Vue 中v-model的完整用法(v-model的实现原理)
  • 原文地址:https://blog.csdn.net/BASK2312/article/details/127997246
    • 最新文章
    • 攻防演习之三天拿下官网站群
      数据安全治理学习——前期安全规划和安全管理体系建设
      企业安全 | 企业内一次钓鱼演练准备过程
      内网渗透测试 | Kerberos协议及其部分攻击手法
      0day的产生 | 不懂代码的"代码审计"
      安装scrcpy-client模块av模块异常,环境问题解决方案
      leetcode hot100【LeetCode 279. 完全平方数】java实现
      OpenWrt下安装Mosquitto
      AnatoMask论文汇总
      【AI日记】24.11.01 LangChain、openai api和github copilot
    • 热门文章
    • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
      奉劝各位学弟学妹们,该打造你的技术影响力了!
      五年了,我在 CSDN 的两个一百万。
      Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
      面试官都震惊,你这网络基础可以啊!
      你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
      心情不好的时候,用 Python 画棵樱花树送给自己吧
      通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
      13 万字 C 语言从入门到精通保姆级教程2021 年版
      10行代码集2000张美女图,Python爬虫120例,再上征途
    Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
    正则表达式工具 cron表达式工具 密码生成工具

    京公网安备 11010502049817号