流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 ...
随机推荐
- es7 await/async解决异步问题
最近做项目遇到一个问题,前端调用ie浏览器中的ocx的方法去查询数据,查询完之后ocx给一个返回值,然后js将返回值当参数传入到另外的函数中去做数据处理,但是遇到一个问题是前端需要异步去执行这个过程 ...
- 移动端js调取手机相册和拍照功能
前端可以通过js调取手机的相册和拍照功能,但不能拍视频!!! <!DOCTYPE html> <html lang="en"> <head> & ...
- Spring mvc之 发邮件(qq.163...)
一. 邮件开发涉及到的一些基本概念 1.1.邮件服务器和电子邮箱 要在Internet上提供电子邮件功能,必须有专门的电子邮件服务器.例如现在Internet很多提供邮件服务的厂商:sina.sohu ...
- poj 3294
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 12688 Accepted: 3552 Descr ...
- 51Nod 1632 B君的连通(递归,快速幂)
1632 B君的连通 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 B国拥有n个城市,其交通系统呈树状结构,即任意两个城市存在且仅存在一条交通线将其连接.A国是B ...
- c语言基础学习01
=============================================================================每一种语言都有其独特的语法规则与语言定义. 指 ...
- ThoughtWorks University之旅 —— 印度游记
ThoughtWorks University是ThoughtWorks为新加入的员工提供的入职培训项目之一,会将世界各地office新入职的员工一起带到印度浦那,参加一次为期5周的培训,内容涵盖了公 ...
- ASP.NET CORE MVC 2.0 项目中引用第三方DLL报错的解决办法 - InvalidOperationException: Cannot find compilation library location for package
目前在学习ASP.NET CORE MVC中,今天看到微软在ASP.NET CORE MVC 2.0中又恢复了允许开发人员引用第三方DLL程序集的功能,感到甚是高兴!于是我急忙写了个Demo想试试,我 ...
- React Native之使用导航器跳转页面(react-navigation)
react-navigation是一个导航库,要使用react-navigation来实现跳转页面,首先得在项目中安装此库,由于Yarn是Facebook提供的替代npm的工具,可以加速node模块的 ...
- 基于逆波兰式的JAVA计算器
请看下方↓↓