点击关注公众号,实用技术文章及时了解

来源:juejin.cn/post/6844903842132262926

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

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().collect(Collectors.toList());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();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> 中 Object 某个属性去重

2.1 新建一个列表出来
@Testpublic void distinctByProperty1() throws JsonProcessingException {// 这里第一种方法我们通过新创建一个只有不同元素列表来实现根据对象某个属性去重ObjectMapper objectMapper = new ObjectMapper();List<Student> 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 <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {Set<Object> seen = ConcurrentHashMap.newKeySet();return t -> seen.add(keyExtractor.apply(t));
}

使用如下:

@Testpublic void distinctByProperty2() throws JsonProcessingException {// 这里第二种方法我们通过过滤来实现根据对象某个属性去重ObjectMapper objectMapper = new ObjectMapper();List<Student> 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. 总结

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

推荐

主流Java进阶技术(学习资料分享)

Java面试题宝典

加入Spring技术开发社区

PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!

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

  1. 通过stream去重_分享几种 Java8 中通过 Stream 对列表进行去重的方法

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

  2. java中给对象的List集合去重的几种方法(Lambda)

    java中给对象的List集合去重的几种方法 前言 一.lambda表达式的去重方式 二.Stream API中的collect去重方法 三.Stream API 中的distinct方法去重 前言 ...

  3. Java8中的Stream

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

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

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

  5. java8中的Stream用法详解

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

  6. list contains方法_Java中给List去重的5种方法,谁的效率更高?

    刚开始学习list的时候就学习了在list集合中如何去除重复数据,当时第一想到的就是通过循环判断来去除重复数据,后来慢慢接触的东西多了,就开始注重一个效率,当数据量巨大的时候,怎么样才能查的更快,怎样 ...

  7. 《 Python List列表全实例详解系列(四)》__列表删除元素(4种方法)删除重复元素(去重)(8种方法)

    <  Python List列表全实例详解系列(四)> __列表删除元素(4种方法)删除重复元素(去重)(8种方法) 我的技术成长&学习资料整理分享之路 我遇到问题查找资料时,经常 ...

  8. Python列表去重的几种方法和实例

    Python列表去重的几种方法和实例 在 Python 中,列表去重有多种方法,下面分别介绍这些方法的实现. 方法一:使用 set() 函数 set() 函数可以将列表转换成集合,集合中不允许有重复的 ...

  9. python list去重函数_python中对list去重的几种方法

    这篇文章主要介绍了python中对list去重的多种方法,现在分享给大家,需要的朋友可以参考下 今天遇到一个问题,在同事随意的提示下,用了 itertools.groupby 这个函数.不过这个东西最 ...

最新文章

  1. C语言字符char和整型int的关系
  2. 转:Android判断当前网络是否可用--示例代码
  3. 关于owa over https的邮箱加密访问
  4. ssh、私钥、密钥理解
  5. jvm3---垃圾回收器算法
  6. 微信小程序使用阿里巴巴矢量库图标
  7. 阿里云推送ReactNative简单集成
  8. python中每个if条件后面都要使用冒号_每个if条件后面都要使用冒号。
  9. character在mysql什么类型_character是什么字段类型
  10. Java-常用实现分页查询
  11. 白岩松:不平静,就不会幸福
  12. 面对混合云与多云挑战,IBM如何助力企业数字化转型?
  13. (附源码)计算机毕业设计SSM科技类产品众筹系统
  14. 芯盾时代完成3亿元C轮融资,宽带资本领投
  15. 如何改变this指向?
  16. docker容器创建
  17. web期末大作业 使用HTML+CSS制作蓝色版爱宠之家带留言板(5页)
  18. dom4j生成xml节点内容换行
  19. 关于网络传输中速度达不到很高的原因
  20. 税务会计实务【21】

热门文章

  1. 快手员工泄露10亿元公司机密 被开除并收回期权,官方暂未回应...
  2. 小米投资偏爱智能与芯片 雷军:有3家科创板上市
  3. 吊打6599元的三星?买手机莫慌 三款国产新手机将发
  4. 逆天了!小米将首发一亿像素手机
  5. 2019款iPhone XR新配色机模上手:就是这个味儿
  6. 锐龙5 3600偷跑 性能直逼酷睿i9-9900K
  7. 易到追债贾跃亭 乐视回应:对方无耻甩锅
  8. 还不懂!软件测试(功能、接口、性能、自动化)详解
  9. 初入c++ (八) c++输入和输出
  10. AudioTrack 播放PCM音频数据