首页 > 其他分享 >lambda表达式与流处理(三)

lambda表达式与流处理(三)

时间:2023-11-07 16:34:23浏览次数:29  
标签:Stream 处理 数据 流中 接口 分组 方法 表达式 lambda

14.3 流处理

流处理有点类似数据库的SQL语句,可以执行非常复杂的过滤、映射、查找和收集功能,并且代码量很少。

1.流处理的接口都定义在java.uil.stream包下。BaseStream接口是最基础的接口,但最常用的是BaseStream接口的一个子接口——Stream接口,基本上绝大多数的流处理都是在Stream接口上实现的。

2.Stream接口是泛型接口,所以流中操作的元素可以是任何类的对象。

Stream接口的常用方法如表14.3所示。

表14.3中最后一列“类型”中有两个值:中间操作和终端操作。中间操作类型的方法会生成一个新的流对象,被操作的流对象仍然可以执行其他操作终端操作会消费流,操作结束之后,被操作的流对象就不能再次执行其他操作了。这是两者的最大区别。

 Collection接口新增两个可以获取流对象的方法。第一个方法最常用,可以获取集合的顺序流,方法如下:

因为所有集合类都是Collection接口的子类,如ArrayList类、HashSet类等,所以这些类都可以进行流处理。例如:

 14.3.2 Optional类

1.Optional类像是一个容器,可以保存任何对象,并且针对NullPointerException空指针异常做了优化,保证Optional类保存的值不会是null。因此,Optional类是针对“对象可能是null也可能不是null”的场景为开发者提供了优质的解决方案,减少了烦琐的异常处理。

2.Optional类是用final修饰的,所以不能有子类。Optional类是带有泛型的类,所以该类可以保存任何对象的值。

optional类中有一个叫作value的成员属性,这个属性就是用来保存具体值的。value是用泛型T修饰的,并且还用了final修饰,这表示一个Optional对象只能保存一个值。

 

 14.3.3 Collectors类

Collectors类为收集器类,该类实现了java.util.Collector接口,可以将Stream流对象进行各种各样的封装、归集、分组等操作。

同时,Collectors类还提供了很多实用的数据加工方法,如数据统计计算等。Collectors类的常用方法如表14.5所示。

14.3.4 数据过滤

 

 数据过滤就是在杂乱的数据中筛选出需要的数据,类似SQL语句中的WHERE关键字,给出一定的条件,将符合条件的数据过滤并展示出来。

1.filter()方法filter()方法是Stream接口提供的过滤方法。该方法可以将lambda表达式作为参数,然后按照lambda表达式的逻辑过滤流中的元素。过滤出想要的流元素后,还需使用Stream提供的collect()方法按照指定方法重新封装。

【例14.16】输出1~10中的所有奇数

这个实例把“获取流”“过滤流”“封装流”3个部分操作分开编写,是为了方便读者学习理解,通常为了代码简洁,3部分操作可以写在一行代码中,例如:

这种写法也可以避免终端操作造成的“流被消费掉”的问题,因为每次被操作的流都是从集合中重新获取的。

 

【例14.17】找出年龄大于30的员工

本实例使用了例14.14定义的Employee类,在获取员工集合后,将年龄大于30的员工过滤出来。如果将员工集合返回的流对象泛型定义为<Employee>,就可以直接在lambda表达式中使用Employee类的方法

2.distinct()方法

distinct()方法是Stream接口提供的过滤方法。该方法可以去除流中的重复元素,效果与SQL语句中的DISTINCT关键字一样。

【例14.18】去除List集合中的重复数字

因为distinct()方法属于中间操作,所以可以配合filter()方法一起使用。

3.limit()方法

limit()方法是Stream接口提供的方法,该方法可以获取流中前N个元素。

 【例14.19】找出所有员工列表中的前两位女员工

 4.skip()方法

skip()方法是Stream接口提供的方法,该方法可以忽略流中的前N个元素。

【例14.20】取出所有男员工,并忽略前两位男员工

14.3.5 数据映射

数据的映射和过滤概念不同:过滤是在流中找到符合条件的元素,映射是在流中获得具体的数据。

Stream接口提供了map()方法用来实现数据映射,map()方法会按照参数中的函数逻辑获取新的流对象,新的流对象中元素类型可能与旧流对象元素类型不相同。

【例14.21】获取开发部所有员工的名单

本实例使用了例14.14定义的Employee类,在获取员工集合后,先过滤出开发部的员工,再引用员工类的getName()方法作为map()方法的映射参数,这样就获取到开发部员工名单。

 结果输出了开发部两位员工的名字,但没有输出这两位员工的其他信息,这个就是映射的结果。

除了可以映射出员工名单,还可以对映射数据进行加工处理。例如,统计销售部一个月的薪资总额。因为涉及数字计算,所以需要让Stream对象转为可以进行数学运算的数字流。因为薪资类型是double类型,所以应该调用mapToDouble()方法进行转换。

【例14.22】计算销售部一个月的薪资总额

除DoubleStream类外,java.util.stream包还提供了IntStream类和LongStream类以应对不同的计算场景。

14.3.6 数据查找

本节所讲的数据查找并不是在流中获取数据(这属于数据过滤),而是判断流中是否有符合条件的数据,查找的结果是一个boolean值或一个Optional类的对象。本节将讲解allMatch()、anyMatch()、noneMatch()和findFirst()这4个方法。

1.allMatch()方法allMatch()方法是Stream接口提供的方法,该方法会判断流中的元素是否全部符合某一条件,返回结果是boolean值。如果所有元素都符合条件则返回true,否则返回false。

【例14.23】检查所有员工是否都大于25岁

2.anyMatch()方法anyMatch()方法是Stream接口提供的方法,该方法会判断流中的元素是否有符合某一条件,只要有一个元素符合条件就返回true,如果没有元素符合条件才会返回false。

3.noneMatch()方法

noneMatch()方法是Stream接口提供的方法,该方法会判断流中的所有元素是否都不符合某一条件。这个方法的逻辑和allMatch()方法正好相反。

【例14.25】检查公司是否不存在薪资小于2000元的员工

4.findFirst()方法

findFirst()方法是Stream接口提供的方法,这个方法会返回符合条件的第一个元素。

注意这个方法的返回值不是boolean值,而是一个Optional对象。

 14.3.7 数据收集

 

 数据收集可以理解为高级的“数据过滤+数据映射”,是对数据的深加工。本节将讲解两种实用场景:数据统计和数据分组。

1.数据统计

数据统计不仅可以筛选出特殊元素,还可以对元素的属性进行统计计算。这种复杂的统计操作不是由Stream实现的,而是由Collectors收集器类实现的,收集器提供了非常丰富的API,有着强大的数据挖掘能力。

【例14.27】统计公司各项数据,打印成报表

 2.数据分组

数据分组就是将流中元素按照指定的条件分开保存,类似SQL语言中的“GROUP BY”关键字。分组之后的数据会按照不同的标签分别保存成一个集合,然后按照“键-值”关系封装在Map对象中。

数据分组有一级分组和多级分组两种场景

Collectors类提供的groupingBy()方法就是用来进行分组的方法,方法参数是一个Function接口对象,收集器会按照指定的函数规则对数据进行分组。

【例14.28】将所有员工按照部门分组

 介绍完一级分组后,再介绍一下复杂的多级分组。

一级分组是按照一个条件进行分组,那么多级分组就是按照多个条件进行分组。还是用学校举例,学校有100个学生,这些学生分布在3个年级中,这是一级分组,但每个年级还有若干个班级,学生们分到不同年级之后又分到不同的班,这就是二级分组。如果学生再按男女分组,就变成了三级分组。元素按照两个以上的条件进行分组,就是多级分组。

Collectors类提供的groupingBy()方法还提供了一个重载形式:

这个重载方法的第二个参数也是一个收集器,当分组前数据包含其他分组的结果,这就构成了多级分组功能。

【例14.29】将所有员工先按照部门分组,再按照性别分组

 

 

标签:Stream,处理,数据,流中,接口,分组,方法,表达式,lambda
From: https://www.cnblogs.com/xiaozhou123456/p/17814987.html

相关文章

  • 无涯教程-批处理 - MORE函数
    此批处理命令一次显示一个或多个文件的内容。MORE-语法More[filename]其中filename是一次需要在一个屏幕上列出其内容的文件。MORE-示例@echooffMoreC:\tp\lists.txtDirectoryofC:\ProgramFiles上面的命令将一次显示一个屏幕,显示文件lists.txt的内容。以下是输......
  • Python文件操作和异常处理
    记录2023.11.7学习文件操作文件计算机处理信息,需要长久保存,使用文件来进行处理。按照内部数据的组织形式,分为:文本文件和二进制文件两类。文件分类文本文件若干行以编码存储的字符组成。通常每行以换行符结尾。二进制文件除了文本文件之外的文件都称为二进制文件。以字节串形式存储,......
  • redis连接满的问题处理
    redis连接满的问题处理1、ver环境系统登录失败ver环境登录失败,报错:cannotgetresource2、查看日志查看日志发现报错信息:maxnumberofclientsreached尝试登录redis发现无法登录redis,报错信息同上。3、问题排查及处理首先重启redis,使用以下命令查看redis的连接数:infoc......
  • BindException、ConstraintViolationException、MethodArgumentNotValidException入参
    Springvalidation验证框架注解Springvalidation验证框架提供了大量接口入参检验注解,注意三个非空注解:@NotNull:验证对象是否不为null,无法查检长度为0的字符串@NotBlank:检查约束(字符串)是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格@NotEmpty:检查(集合)......
  • selenium等待元素加载,元素操作,执行js,切换选项卡,前进后退,异常处理,登录cnblogs,抽
    1selenium等待元素加载......
  • C++ lambda函数总结
    C++lambda函数1lambda函数简介名称lambda来自lambdacalculus(lambda演算),一种定义和应用函数的数学系统。这个系统中可以使用匿名函数,对于接收函数指针或伪函数的函数,可以使用匿名函数定义(lambda)作为其参数。1.1为什么使用lambda函数?距离:定义位于使用的地方附近很有用,由于......
  • Util应用框架基础(五) - 异常处理
    本节介绍Util应用框架如何处理系统错误.概述系统在运行过程中可能发生错误.系统错误可以简单分为两类:系统异常系统本身出现的错误.业务异常不满足业务规则出现的错误.如何处理系统异常如果发生系统异常,大多数情况下,你除了记录异常日志外,可能无法处理它们.一个......
  • 一个List对象,想把特定的值排在最前面进行处理
    今天遇到一个需求,要把list中的某些特定的值排在最前面处理,所以就要对list进行排序,搜索了一下进行总结首先对List<String>根据特定的值进行排序List<String>list=Arrays.asList("apple","banana","cherry","date","sss","fig");Li......
  • GuzzleHttp 超时后处理
     publicfunctionhttpTest(){$url="自己可以写一个模拟地址,例如下面的httpTest2先让他挂起一定的时间,timeout设置超时时间,如果超过timeout的时间会自动抛出异常,去发短信等...";$client=newClient();try{$respo......
  • 先进的文档处理技术——Apryse介绍
    为开发人员提供先进的文档处理技术我们的SDK、预构建组件和用户SaaS应用程序使世界先进的公司能够在其应用程序和工作流程中轻松生成、转换、查看、编辑和签署文档。无论您是希望将文档处理功能集成到您的软件中、简化内部工作流程、增强文档审阅,还是在您的企业内协作、编辑......