Stream使用技巧(1)------数据处理技巧

2023-11-07

Stream使用技巧(1)------数据处理技巧

一. 背景

作为java8新特性之一的Stream API为开发者带来了极大的便利,它可以对我们需要操作的集合进行非常复杂的操作,以活的我们想要的结果.

本文不会告诉你什么是Stream,毕竟网上花里胡哨的使用教程已经让我应接不暇,本系列博文只是记录一些Stream的使用技巧,便于方便的查找和参考.

本博文会无限更新,有新的使用方法会逐渐添加进来,如果有小伙伴有新奇的使用技巧,也可以发出来一起分享.

本文中默认使用的对象user如下:

    @Data
    class User {
        /** 名字 **/
        private String name;
        /** 年龄 **/
        private Integer age;
        /** 性别 true男false女 **/
        private boolean sex;

        User(String name, Integer age, boolean sex) {
            this.age = age;
            this.name = name;
            this.sex = sex;
        }
    }
二. 使用案例
1. List<User>转Map<String, Integer>
  • 需求描述:

    有一个List集合,其中的每一个元素都是对象,想变成一个Map,其中key是对象的一个属性,value也是对象的一个属性或者对象本身.

  • 伪代码:

        @Test
        public void test1() {
            User a = new User("张三", 20, true);
            User b = new User("李四", 30, true);
            User c = new User("王五", 40, true);
            List<User> list = new ArrayList<User>();
            list.add(a);
            list.add(b);
            list.add(c);
            //变成Map, key是name, value是age
            Map<String, Integer> collect = list.stream().collect(Collectors.toMap(User::getName, User::getAge));
            System.out.println(collect);
        }
    
    
  • 结果:

    {李四=30, 张三=20, 王五=40}
    

2. List<User>转List<String>
  • 需求描述:

    List对象中,提取出每一个User对象的name属性,放在List里面

  • 伪代码:

        @Test
        public void test1() {
            User a = new User("张三", 20, true);
            User b = new User("李四", 30, true);
            User c = new User("王五", 40, true);
            List<User> list = new ArrayList<User>();
            list.add(a);
            list.add(b);
            list.add(c);
            //取出每一个user的name变成list
            List<String> collect = list.stream().map(User::getName).collect(Collectors.toList());
            System.out.println(collect);
        }
        
    
  • 结果:

    [张三, 李四, 王五]
    
3. List<User>转Map<Integer, Map<String, User>>
  • 需求描述

    用户集合中的用户,先按照年龄分组,再按照姓名分组,最终将用户分开

  • 伪代码:

        @Test
        public void test1() {
            User a = new User("张三", 20, true);
            User b = new User("李四", 30, true);
            User c = new User("王五", 40, true);
            User d = new User("花木兰", 40, false);
            User e = new User("李师师", 50, false);
    
            List<User> list = new ArrayList<User>();
            list.add(a);
            list.add(b);
            list.add(c);
            list.add(d);
            list.add(e);
            //取出每一个user的name变成list
            Map<Integer, Map<String, User>> collect =
                    list.stream().collect(Collectors.groupingBy(
                            User::getAge,
                            Collectors.toMap(User::getName, x -> x))
                    );
            System.out.println(collect);
        }
    
  • 结果:

    {50={李师师=SampleStream.User(name=李师师, age=50, sex=false)}, 20={张三=SampleStream.User(name=张三, age=20, sex=true)}, 40={王五=SampleStream.User(name=王五, age=40, sex=true), 花木兰=SampleStream.User(name=花木兰, age=40, sex=false)}, 30={李四=SampleStream.User(name=李四, age=30, sex=true)}}
    
4. List<User>取出一个属性转List<Integer>, 并去重
  • 需求描述

    取出用户集合中的Age字段,放在一个List中,并去重

  • 伪代码:

      @Test
      public void test1() {
          User a = new User("张三", 20, true);
          User b = new User("李四", 30, true);
          User c = new User("王五", 40, true);
          User d = new User("花木兰", 40, false);
          User e = new User("李师师", 50, false);
    
          List<User> list = new ArrayList<User>();
          list.add(a);
          list.add(b);
          list.add(c);
          list.add(d);
          list.add(e);
          //取出每一个user的name变成list
          List<Integer> collect = list.stream().map(User::getAge).distinct().collect(Collectors.toList());
          System.out.println(collect);
      }
    
  • 结果:

    [20, 30, 40, 50]
    
5. List<User>去重并提出空值
  • 需求描述

    用户集合中有两个用户是相同的,且有个null对象,需要得到一个去重去空后的集合

  • 伪代码:

      @Test
      public void test1() {
          User a = new User("张三", 20, true);
          User b = new User("李四", 30, true);
          User c = new User("王五", 40, true);
          User d = new User("王五", 40, false);
          User e = new User("李师师", 50, false);
    
          List<User> list = new ArrayList<User>();
          list.add(a);
          list.add(b);
          list.add(c);
          list.add(d);
          list.add(e);
          list.add(null);
          System.out.println("去重前: " + list);
          //取出每一个user的name变成list
          ArrayList<User> collect = list.stream().filter(Objects::nonNull).collect(
                  Collectors.collectingAndThen(
                          Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))),
                          ArrayList::new)
          );
          System.out.println("去重后: " + collect);
      }
    
  • 结果:

    去重前: [SampleStream.User(name=张三, age=20, sex=true), SampleStream.User(name=李四, age=30, sex=true), SampleStream.User(name=王五, age=40, sex=true), SampleStream.User(name=王五, age=40, sex=false), SampleStream.User(name=李师师, age=50, sex=false), null]
    去重后: [SampleStream.User(name=张三, age=20, sex=true), SampleStream.User(name=李四, age=30, sex=true), SampleStream.User(name=李师师, age=50, sex=false), SampleStream.User(name=王五, age=40, sex=true)]
    
结语:

在本篇博文中,列举了java8中Stream API在实际开发中的一些应用技巧,记录在这里,以后有需要的时候可以及时查阅

个人公众号<橙耘自留地>日前已经开通,后续博主发布的文章都会一并更新到公众号,如有需要,自行查阅.

关于橙耘自留地,是我个人聚焦互联网技术栈学习分享的一个平台,创立之初是因为目前业内各种技术课程资料层次不齐,褒贬不一,有时候一门课花费高价买入,其实内含草包,有时偶尔低价得之,却又大有干货.因此我会根据大家的意见和评价,选择不同的技术栈去学习,一为提升我自己的技术,二为大家梳理出质量比较好的课程,以作参考.同时,相关的学习心得也会一并更新到博客和公众号.

qrcode_for_gh_c1462e34b232_344

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Stream使用技巧(1)------数据处理技巧 的相关文章

  • Openfeign ErrorDecoder 导致 java.io.IOException:流已关闭

    当我尝试实施时ErrorDecoder为了解码假装异常 我在中找到了流response body 已关闭 因此当我尝试读取流并将其转换为字符串时 它会抛出java io IOException stream is closed 这真的很困惑
  • 将猫鼬流转换为数组

    我曾经使用过 mongodb 但对 mongoose ORM 还很陌生 我试图从集合中获取数据 explain 输出显示 50 毫秒 通过 mongoose 获取数据的总时间为 9 秒 这是查询 Node find dataset data
  • C++ 流如何为输入分配空间?

    例如 is type std istream str type std string is gt gt str 这是怎么长出来的str适应输入 它逐个字符地读取并调用str push back 或类似的东西 或者它是否有一种机制可以在读取输
  • 使用OLEDB从Stream读取AccessFile到DataSet

    我使用 Oledb 将 AccessFile accdb 读取到 DataSet 我不知道表名或列 常规实现是 public void GetAccessDB string filepath this ConnectionString Pr
  • 将文本流从 NodeJS 传递到浏览器

    我正在尝试将 NodeJS 中处理的文本文件流式传输到浏览器 以下是处理前的文本文件 该文件名为 dbUsers json userId 443 email email protected cdn cgi l email protectio
  • REtful POST :要写入流的字节超过指定的 Content-Length 字节大小

    抛出此错误 Bytes to be written to the stream exceed the Content Length bytes size specified 当我运行以下代码时 var request HttpWebRequ
  • 如果您不打算从自适应渲染中受益,那么使用 HtmlTextWriter 有什么好处吗?

    除了从替代设备的自适应渲染中受益之外 编写所有这些代码是否有意义 writer WriteBeginTag table writer WriteBeginTag tr writer WriteBeginTag td writer Write
  • 在 Gulp 中将流与事件流连接时的顺序

    在此 Gulp 任务中 vendorFiles 代码放置在 dest style css 文件中的 appFiles 代码之后 这是因为 appFiles 流运行得更快吗 如何让vendorFiles代码按预期出现在前面 gulp task
  • FileStream 添加“额外”字符到 TXT 文件

    无论我读取 TXT 文件还是 XML 文件 我总是会看到 额外 信息添加到保存到磁盘的文件中 我们首先执行以下操作 FileStream fs new FileStream fileMoverFile SourcePath FileMode
  • 如何有效计算文档流中文档之间的相似度

    我收集文本文档 在 Node js 中 其中一个文档i表示为单词列表 考虑到新文档以文档流的形式出现 计算这些文档之间相似性的有效方法是什么 我目前对每个文档中单词的归一化频率使用余弦相似度 我不使用 TF IDF 词频 逆文档频率 因为我
  • C++ 中有标准的日期/时间类吗?

    C stl 有标准时间类吗 或者我是否必须在写入流之前转换为 c 字符串 例如 我想将当前日期 时间输出到字符串流 time t tm ostringstream sout sout lt lt tm lt lt ends 在本例中 我将当
  • 确定 std::istream 长度的更好方法?

    有没有比以下更好的方法来确定 std istream 的长度 std istream pcStream GetSomeStream pcStream gt seekg 0 ios end unsigned int uiLength pcSt
  • 如何将整个流读入 std::string ?

    我正在尝试将整个流 多行 读入字符串中 我正在使用这段代码 它有效 但它冒犯了我的风格感 当然有更简单的方法吗 也许使用字符串流 void Obj loadFromStream std istream stream std string s
  • c# 模拟 IFormFile CopyToAsync() 方法

    我正在对一个异步函数进行单元测试 该函数将 IFormFile 列表转换为我自己的任意数据库文件类列表 将文件数据转换为字节数组的方法是 internal async Task
  • Dart 流 .asBroadcastStream 内存泄漏

    在我们的 Flutter 应用程序中 我们存在内存泄漏和流未关闭的情况 我们追踪源代码如下 Rx combineLatest asBroadcastStream RxDart的结果 combineLatest 是单订阅流 添加 asBroa
  • Nodejs 中的 tail-stream 模块不打印文件的最后一条记录

    我正在使用 tail stream 从 csv 文件获取数据 并将每个 csv 记录转换为 json 格式并打印它 但是尾流不会打印文件的最后一行 而是将其保留为缓冲区 如果我更新文件 则从上一个最后一行 缓冲的最后一行 到更新的最后一行
  • 是否可以检测流是否已被客户端关闭?

    简要介绍一下情况 我有一项服务可以通过套接字接收信息并发送回复 连接不安全 我想设置另一个可以为这些连接提供 TLS 的服务 这个新服务将提供单个端口并根据提供的客户端证书分发连接 我不想使用 stunnel 有几个原因 其中之一是每个接收
  • 如何使用 FS2 中的分类器函数对对象进行分组?

    我有一个无序的流measurements 我想将其分组为固定大小的批次 以便以后可以有效地保留它们 val measurements for id lt Seq foo bar baz value lt 1 to 5 yield id va
  • 使用任何节点模块在内存中创建 ZIP 文件

    是否有任何节点模块可以在内存中创建 zip 我不想将 zip 文件保存在磁盘上 以便我们可以将这个创建的 zip 文件发送到其他服务器 从内存 做这个的最好方式是什么 这是我的例子 var file system require fs va
  • 获取与请求

    我正在使用 JSON 流并尝试使用 fetch 来使用它 该流每隔几秒发出一些数据 仅当流关闭服务器端时 使用 fetch 来使用流才可以访问数据 例如 var target the url var options method POST

随机推荐

  • 怎么注册自媒体账号?技巧分享

    自媒体行业的快速发展 相信大家都有耳闻 至于自媒体应该如何有效地运营 相信大家就纷纷摸不着头脑了那么新手如何做自媒体呢 我归纳分为这几个步骤 一 自媒体账号定位 在做自媒体之前 一定需要做好定位 比如我这个自媒体开通了要拿来做什么 比如给人
  • 强大的Source Insight查找操作和代码查看

    系列文章 一 Source Insight 简介 常用设置和常用的快捷键 二 Source Insight 工程操作 三 Source Insight 窗口介绍 四 强大的Source Insight查找操作和代码查看 五 Source I
  • Logcat 的常用命令说明

    个人认为有一下几个常用命令 adb logcat c 清除所有以前的日志 adb logcat d 这个命令是在时间上倒过来用的 就是你先操作 然后敲这个命令 打出来的log就是你刚操作那段时间的log 而且自动退出log模式 adb lo
  • Vue PostCss插件——autoprefixer,自动补全css浏览器前缀

    Autoprefixer是一款基于PostCSS插件 用于解析CSS并使用Can I Use中的值向CSS规则添加供应商前缀 它是 Google 推荐的 并在Twitter和阿里巴巴中使用 可以实现css3代码自动补全 也可以运用到sass
  • 实例:vmem_disk驱动-->vmem_disk驱动模块的加载与卸载(2)

    支持 制造请求 请求队列 static void setup device struct vmem disk dev dev int which memset dev 0 sizeof struct vmem disk dev dev gt
  • 达蒙DM数据库使用经验

    DM表 字段注释 注 dm数据库无法在建表的同时为字段名添加注释 为表添加注释 comment on table 库名 表名 is 表注释 为表字段添加注释 comment on column 库名 表名 列名 is 列注释 DM查询错误
  • 如何搭建一个CRM系统

    搭建一个客户关系管理系统 CRM 需要以下几个步骤 定义需求 明确您对 CRM 系统的要求 以便确定它应该具有哪些功能和特性 选择技术 根据您的需求 选择合适的技术平台 例如使用自主开发 购买现成软件或使用云 CRM 服务 数据收集 收集所
  • QT中如何在主窗口中添加子窗口

    1 方法 原理其实很简单 和在窗口上动态 代码的形式 添加控件的方法一样 但需要设置一下子窗口的属性 在子窗口构造函数中添加代码 setWindowFlags Qt FramelessWindowHint 作用 隐藏子窗口的标题栏和边框 如
  • 统计各专业学生人数

    题目描述 学生表 专业表 SELECT dept name ifnull z studen cou 0 AS 人数 FROM SELECT dept id COUNT AS cou FROM z studen GROUP BY dept i
  • 一种设置python函数执行超时时间

    问题来源 写该文章的缘由是因为最近回答CSDN用户一个关于函数超时的问题 当时用户提问 最近想用python实现如下的一个功能 即设置函数的超时时间 当超过这个时间后函数退回到父函数而不会引发异常或导致整个程序结束 当时用户还贴出了另一篇文
  • Python 朴素贝叶斯(Naive Bayes)分类

    Na ve Bayes 分类的核心是计算条件概率P y x 其中y为类别 x为特征向量 其意义是在x样本出现时 它被划分为y类的可能性 概率 通过计算不同分类下的概率 进而把样本划分到概率最大的一类 根据条件概率的计算公式可以得到 P y
  • oracle_11 linux客户端安装说明以及如何添加sqlldr命令

    1 安装文件准备 oracle instantclient11 2 basic 11 2 0 2 0 x86 64 rpm oracle instantclient11 2 devel 11 2 0 2 0 x86 64 rpm oracl
  • Th4.2:类模板的概念、类模板的定义和使用之详述

    本小节回顾的知识点分别是类模板的概念 类模板的定义和使用 今天总结的知识分为以下4个点 1 概述 2 类模板定义 3 类模板的成员函数 4 非类型模板参数 1 概述 类模板 就是包含待指定数据类型的类 这个待指定的数据类型就是类模板的模板参
  • Centos7安装Python3的方法(亲测高效)

    Centos7下安装Python3的方法 由于centos7原本就安装了Python2 而且这个Python2不能被删除 因为有很多系统命令 比如yum都要用到 root VM 105 217 centos Python 3 6 2 pyt
  • css布局中关于 块状元素和行内元素的区分

    这两天在准备实习的面试和笔试 准备复习一下这些基础的概念 避免自己处于一种仅脑袋理解嘴巴不能表述出来的状态 块状元素和行内元素的概念是在css页面布局这个地方出现 主要是将html标签按照一定的特性分成2类 块状元素和行内元素 内联元素 首
  • 循环双向链表

    循环双向链表 1 简介 单链表 总是从头到尾找结点 难道就不可以正反遍历都可以吗 当然可以 只不过需要加点东西而已 有了 next 指针 这就使得我们要查找下 结点的时同复杂度为 1 可是如果我们要查找的是上一结点的话 那最坏的时间复杂度就
  • Linux:死锁与解决方法

    死锁 死锁 指在一组进程中的各个进程均占有不会释放的资源 但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态 死锁现象 现象1 如果执行流加锁完毕后 不进行解锁则会造成死锁 上篇所述 现象2 线程A获取了1锁 线程B获取了2
  • [Qt5.12.3] 使用Chart模块中warning: ‘setAxisX‘ is deprecated, warning: ‘setAxisY‘ is deprecated的解决办法

    文章目录 问题描述 解决方案 后记 问题描述 在使用QtCharts模块绘图的过程中 X轴需要显示DateTime 不能使用默认的createDefaultAxes 遂使用了setAxisX setAxisY方法 但一直报方法被弃用 虽暂时
  • Latex: 参考文献双栏对齐

    参考 How to level columns in bibliography Latex 参考文献双栏对齐 需要实现的效果 方法1 在开头引用balance usepackage balance 在文末 参考文献前 加上 balance
  • Stream使用技巧(1)------数据处理技巧

    Stream使用技巧 1 数据处理技巧 一 背景 作为java8新特性之一的Stream API为开发者带来了极大的便利 它可以对我们需要操作的集合进行非常复杂的操作 以活的我们想要的结果 本文不会告诉你什么是Stream 毕竟网上花里胡哨