流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 ...
随机推荐
- 入门干货之Grpc的.Net实现-MagicOnion
此文章简单残暴,学习成本较低,你可以跟着我一起撸代码,一起吐槽,一起砸键盘.以下操作均为 core2.0 环境. 0x01.Grpc 1.介绍 Google主导开发的RPC框架,使用HTTP/2协议 ...
- 管理 MariaDB 用户账户
哪些用户可以连接到MariaDB 服务器,他们都可以从哪些地方连接,连接到服务器后又能够做什么等,都是本文将涉及到的内容. 用户的权限信息都保存在 mysql 库中的几个权限表中.对 MariaDB ...
- Android数据库之判断表是否存在
Android开发的时候我们可能会用到它的本地数据库,在使用的时候有可能我们已经储存了数据了,但是,我们的表已经创建了,里面有数据,我们要怎么判断表是否已经创建可能就需要琢磨一下. 以下便是利用了,查 ...
- Redis随笔(二)redis desktop manager 安装并且连接redis服务器
1.首先在win10下安装redis desktop manager 2.查看虚拟机防火墙状态,启动状态,则关闭掉 查看防火墙状态: systemctl status firewalld.servic ...
- Java与算法之(6) - 八皇后问题
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. (文字和图片来自百度百科) 如果动手来摆放皇后,可以用这样一种思路:在最左侧 ...
- 【转】TCP粘包分析
一 .两个简单概念长连接与短连接: 1.长连接 Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收. 2.短连接 Client方与Server每 ...
- deeplearning.ai 构建机器学习项目 Week 2 机器学习策略 II 听课笔记
1. 误差分析(Error analysis) 误差分析的目的是找到不同误差源的比重,从而指引我们接下来往哪个方向努力改进.NG建议手工统计随机100个错误的误差源,比如对于猫分类器,错误的照片可能是 ...
- cs231n spring 2017 lecture4 Introduction to Neural Networks 听课笔记
1. Backpropagation:沿着computational graph利用链式法则求导.每个神经元有两个输入x.y,一个输出z,好多层这种神经元连接起来,这时候已知∂L/∂z,可以求出∂L/ ...
- MongoDB(一)环境搭建与初始配置
前言 最近的项目中需要用到MongoDB,所这段时间需要学习知道怎么去使用这个数据库. 这里我先简单的介绍一下什么是MongoDB,后面还会详细的介绍: MongoDB 是一个面向文档的通用型数据库, ...
- 2-Sat+输出可行解(个人模版)
2-Sat+输出可行解: //LightOJ 1251 #include<stdio.h> #include<string.h> #include<vector> ...