流API--缩减操作
在Stream流操作中,比如说min(),max(),count()方法,这几个操作都会将一个流缩减成一个值,流API将这些操作称为特例缩减。另外,流API同时泛华了缩减这种概念,提供了reduce()方法,通过使用reduce()方法,可以基于任意条件,从流中返回一个值。根据定义,所有缩减操作都是终端操作。
我们先来翻下api:
Optional<T> reduce(BinaryOperator<T> accumulator) :Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.
T reduce(T identity, BinaryOperator<T> accumulator) :Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value.
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner):Performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions.
先来看一段代码演示下如果对一个流做缩减操作:
public static void main(String[] args) throws Exception
{
List<Integer> list = new ArrayList<>(4);
list.add(1);
list.add(2);
list.add(3);
list.add(4);
//reduce第一个重载,直接进行缩减
list.stream().reduce((a, b) -> a + b).ifPresent(System.out::println);
//reduce第二个重载,可以指定初始值,然后在进行缩减
System.out.println(list.stream().reduce(0, Integer::sum));
//reduce第三个重载,可以指定初始值,然后在进行缩减,第3个参数用来处理并行流的操作
System.out.println(list.stream().reduce(0, (a, b) -> a * 2 + b, (c, d) -> c + d));
List<String> list1 = Lists.newArrayList("1", "2", "3", "4");
System.out.println(list1.stream().reduce(1, (a, b) -> a + b.length(), (c, d) -> c + d));
}
这里我们重点要看下前面2个方法:
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)
第一个方法返回一个Optional对象,该对象包含了结果。第二个方法直接返回T类型的对象,这里的这个T类型就是流中元素的类型。在使用这2个方法的时候,要传入一个Lambda表达式,这个表达式要实现BinaryOperator<T>函数式接口,先说下这个接口吧:具体的可以去看我前面有篇博客的,这些函数式接口很容易忘掉了,我晕。
public interface BinaryOperator<T> extends BiFunction<T,T,T> {}
这个函数式接口扩展了BiFunction<T,T,T> 接口,这里只不过赋值方法的参数是同一个类型,然后返回值也是同一个类型而已。对于,BinaryOperator<T> 来说,apply方法现在变成了如下方法:
T apply(T val, T value);其中val将包含前一个结果,然后value包含下一个元素。我们在调用reduce的时候,val将包含单位初始值或者第一个元素。在上面2个方法中,第一个方法将包含第一个元素,第二个方法将包含单位值。
注意:
累加器操作必须满足以下3个约束:
1,无状态
2,不干预
3,结合性
无状态意味着操作不依赖于任何状态信息,不干预意味着操作不会改变数据源,最后操作必须具有关联性。这里的关联性可以理解为加法结合律或者乘法结合律,举个例子,(a+b)+c=a+(b+c);
最后这里整理下reduce的第3个重载方法:
reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)。
考虑如下情景:假设我们现在有一个包含多个对象的流,并且希望对他们的某个属性进行求和。例如求一个流中的所有字符串的总长度,这个时候我们没有办法用上面的2个reduce的重载,因为上面2个方法中需要一个(T,T)->T这样子的函数式接口,但是这里这2个类型是不同的,流中的元素是String的,但是累加的结果是整型的。对于这种情况,我们只能使用重载的第3个方法了。
public static void main(String[] args)
{
Stream<String> of = Stream.of("张飞", "关羽");
//一下代码报错,类型不匹配The method reduce(String, BinaryOperator<String>) in the type Stream<String>
//is not applicable for the arguments (int, BinaryOperator<String>)
of.reduce(0, (a, b) -> a + b.length());
System.out.println(of.reduce(0, (a, b) -> a + b.length(), Integer::sum));
}
流API--缩减操作的更多相关文章
- Java8 Stream流API常用操作
Java版本现在已经发布到JDK13了,目前公司还是用的JDK8,还是有必要了解一些JDK8的新特性的,例如优雅判空的Optional类,操作集合的Stream流,函数式编程等等;这里就按操作例举一些 ...
- 【JDK8】Java8 Stream流API常用操作
Java版本现在已经发布到JDK13了,目前公司还是用的JDK8,还是有必要了解一些JDK8的新特性的,例如优雅判空的Optional类,操作集合的Stream流,函数式编程等等;这里就按操作例举一些 ...
- 通过流的方式操作hadoop的API
通过流的方式操作hadoop的API 功能: 可以直接用来操作hadoop的文件系统 可以用在mapreduce的outputformat中设置RecordWrite 参考: 概念理解 http:// ...
- java8-Stream流API
一回顾与说明 经过前面发布的三章java8的博客,你就懂得了我们为什么要用Lamda表达式,Lamda表达式的原理与函数式接口的关系,从Lamda表达式到方法引用和构造引用. 想要学Stream流你必 ...
- 恕我直言你可能真的不会java第11篇-Stream API终端操作
一.Java Stream管道数据处理操作 在本号之前写过的文章中,曾经给大家介绍过 Java Stream管道流是用于简化集合类元素处理的java API.在使用的过程中分为三个阶段.在开始本文之前 ...
- Python 完美诠释"高内聚"概念的 IO 流 API 体系结构
1. 前言 第一次接触 Python 语言的 IO API 时,是惊艳的.相比较其它语言所提供的 IO 流 API . 无论是站在使用者的角度还是站在底层设计者的角度,都可以称得上无与伦比. 很多人在 ...
- InfluxDB学习之InfluxDB的HTTP API查询操作
在 InfluxDB学习 的上一篇文章:InfluxDB学习之InfluxDB的HTTP API写入操作 中,我们介绍了使用InfluxDB的HTTP API进行数据写入操作的过程,本文我们再来介绍下 ...
- InfluxDB学习之InfluxDB的HTTP API写入操作
HTTP API也有两种操作:写入和查询,本文就先给大家介绍一下 InfluxDB的HTTP API的写入操作方式. 在InfluxDB学习的上一篇文章:InfluxDB学习之InfluxDB ...
- 利用Fiddler修改请求信息通过Web API执行操作(Action)实例
本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复261或者20170724可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...
随机推荐
- 【高精度乘法】NOIP2003麦森数
题目描述 形如2^{P}-12P−1的素数称为麦森数,这时PP一定也是个素数.但反过来不一定,即如果PP是个素数,2^{P}-12P−1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的 ...
- 表迁移工具的选型-复制ibd的方法
1.1. 场景 有的时候开放人员自己的库需要帮忙导一些数据,但是表的数据量又很大.虽然说使用mysqldump或mysqlpump也可以导.但是这耗时需要比较久. 记得之前建议开放人员可以直接使用na ...
- Kafka、Logstash、Nginx日志收集入门
Nginx作为网站的第一入口,其日志记录了除用户相关的信息之外,还记录了整个网站系统的性能,对其进行性能排查是优化网站性能的一大关键. Logstash是一个接收,处理,转发日志的工具.支持系统日志, ...
- True 和 False
True 和 False是Python中的关键字. 'True' 和 'False'是Python中的字符串. true 和 false 是Python中的变量名,需要提前定义.
- springMvc项目的搭建,暂时没有整合持久层框架(java Config配置对比xml配置)
public class WebInit implements WebApplicationInitializer { @Override public void onStartup(ServletC ...
- React Native学习(一)——搭建开发环境
第一次接触React Native,首先搭建环境,过程还算顺利,不过也遇到了些问题,这里简单记录下来.中文官网(http://reactnative.cn/docs/0.47/getting-star ...
- flask-日料网站搭建-数据库操作
引言:想使用python的flask框架搭建一个日料网站,主要包含web架构,静态页面,后台系统,交互,目前已经copy完主页,不是前端太慢太慢. 本节知识:数据库的操作,模型建表,更新数据库. py ...
- JavaScript中数组map()方法
JavaScript 数组map()方法创建一个新的数组使用调用此数组中的每个元素上所提供的函数的结果.语法 ? 1 array.map(callback[, thisObject]); 下面是参数的 ...
- 2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】
Big binary tree Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- Windows系统下文件的概念及c语言对其的基本操作(甲)
文件概念