本章我们将会了解到关于Stream API的很多操作,这些操作能够完成很多复杂的查询,比如,比如筛选,切片,映射,查找,匹配和规约,
第一节,筛选和切片
首先我们来看看用谓词来选择流动的元素,主要介绍了几个基础操作,包括:filter, distinct, limit, skip等。
比如对于filter,这里给了上一章的一个例子,用一个谓词来判断一个菜单中是否有蔬菜:
List<Dish> vegetarianMenu = menu.stream().filter(Dish::isVegetarian).collect(toList());
第二节, 映射
主要有两种意思,一种是对流中的每一个元素应用映射,第二种就是流的扁平化
map, flatMap
所谓流量变化,主要是为了解决流嵌套流在这种场景,而它们最终变成一个流。
这里给了一个例子,让我们返回一个句子中,每一个单词里面的,各不相同的字符,他最终是这么写的:
List<String> uniqueChar = words.stream().map(w->split("")).flatMap(Arrays::stream).distinct.collect(toList());
一言以蔽之,流的扁平化就是让你把一个流中的每一个值都转换成另外一个流,然后把所有的流连接起来成为一个流,比如上面的这个例子,map(w-> split(""))把每个单词都转化为一个字符串数组,然后通过Arrays::stream把每个字符串数组转换成一个流,然后再通过flatMap把它们合并成一个流。
本节的末尾作者给了一个例子,坐在给了两个数组,然后要用线性代数里面的数字相乘的,逻辑来生成一系列的数对,这个例子我一开始没有做出来,所以我觉得,可以用这个例子,来作为面试题。当我没有说出来,是因为一开始我对于这个flatMap理解不够深刻,现在应该没什么问题,简单写一个示意代码。
List<Integer> array1 = Arrays.asList(1,2,3);
List<Integer> array2 = Arrays.asList(3, 4);
List<int[]> result = array1.stream().flatMap( a-> array2.stream(b-> new int[]{a, b})).collect(toList());
第三节,查找和匹配
这一节主要介绍了以下几种常见的处理函数:
allMatch, anyMatch, noneMatch, findFirst, findAny.
这里提到了,短路的概念,所谓短路,也就是说不管表达是有多惨,你只需要找到一个表达式为false,就可以推断整个表达式微false,所以用不着去计算整个表达式。
接下来在介绍查找元素的时候,作者提到了一个新的类 Optional<T>,这是一个容器类,代表1个值存在或者不存在,比如findAny可能什么都没找到,有了这个类我们就可以不用返回众所周知容易出问题的null,从而避免了和null相关的一些bug。
这里我们可以记住,Optional类的一些API:
isPresent()
ifPresent(Comsumer<T>),会在值存在的时候,执行一段指定的代码块。
T get()
T orElse(T other) 值存在的时候就返回值,不存在的时候就返回默认值,
本节等最后作者分析了findFirst 和findAny之间的区别,两者在并行计算的时候性能是不一样的。
第四节,规约
本节你将看到,如何把一个流中的所有的元素组合起来,使用reduce操作来表达一个更复杂的查询,此类查询需要把流中的所有元素反复结合起来,得到一个值,比如一个整形。这样的查询可以被归类为规约操作,如果用函数式编程的术语来说叫做折叠。
第一小节,求和操作
int sum = numbers.stream().reduce(0, (a, b) -> a+b));
等效于:
int sum = numbers.stream().reduce(Integer::sum);
这里用到了reduce操作就是当年google的赫赫有名的map-reduce中的reduce
上文用到的reduce等原型是:函数介绍一个初始值,然后用一个,二元操作符,
其实reduce还有另外一个变体,就是只介绍一个二操作符,这个时候,他就必须返回上文提到的那个Optional类了,因为没有默认初始值啊,所以可能是空的。
想这个辩题呢,就还可以用这个reduce操作计算最大最小值
然后本节的最后作者提出了规约操作的并行化:
int sum = numbers.parallelStream().reduce(0, Integer::sum);
按作者同时也提出,规约操作要有并行化的话要付出一定的代价的,也就是这个规约函数,必须是无状态的,而且操作本身必须,满足结合定律才可以按照任意顺序执行。
流操作做其实可以分为无状态、有状态有界和有状态无界3种,
1)比如map和filter,就属于无状态的,
2)reduce操作中等max、sum这样的操作则是有状态的。但是他们内部状态所需要的存储空间很小,所以属于有界的。
3)而像sort、distinct这些操作,他们基本上是输入一个流说出一个流,如果流比较大,或者是无限的,那么他们所需要的存储空间也是无限的。
第五节,付诸实践,
这一节以一个交易员在日常工作中所遇到的一些关于交易的例子来说明就操作的相关api的应用。
题目如下,怎么做我就不说了,
第六节,数据流
感觉一开始作者就给了一个例子,如果没有数据流,我们,所使用的球和操作可能会有什么问题,比如:
int calories = menu.stream().map(Dish::getCalories).reduce(0, Integer::sum);
这里面主要按了一个装箱的成本, 也就是说所有的数字在计算的时候必须被转换成Integer类型,计算完之后再转换会int。这样如果留,比较大的时候,其实对性能的,影响还是比较大的,所以,在java8中,Stream API提供了原始类型的流特化。专门支持处理数据流的方法。
第一小节,原始类型流特化
在java8中,引入了,三个,原始类型特化流接口: IntStream, DoubleStrream, LongStream,分别将流中等元素特化为int, double, long类型,从而避免了暗含的装箱成本。
将流转换为特化版本的常用方法有:mapToInt, mapToDouble, mapToLong,比如:
int calories = menu.stream().mapToInt(Dish::getCalories).sum();
其中sum是IntStream特化流中特有的接口。
如果要计算一个特化流中的最大值,那么他就会返回一个Optional<T>,因为流可能是空的,那么这个时候就没有最大值了。
既然可以将流转化为一个特化流,同样的也可以讲一个特化流转化为非特化流,相应等方法就是:boxed()
第二小节,数值范围
主要有两个方法:
IntStream.range(1, 100)
IntStream.rangeClosed(1, 100)
一个是开区间,一个是闭区间。
第三小节,数据流的应用,勾股数
Stream<int[]> pythagoreamTriples = IntStream.rangeClosed(1, 100)
.flatMap(a -> IntStream.rangeClosed(a, 100).map(b->new double[] {a, b, Math.sqrt(a*a + b*b)}))
.filter(a->a[2] %1 == 0);
第七节,构建流
本节我们将介绍如何从值序列、数组、文件来创建流,甚至可以通过一个函数来创建无限流。
第一种,通过值来创建
Stream<String> ss = Stream.of("Hello", "world", "ni hao");
或者你可以直接创建一个空流
Stream<String> ss = Stream.empty();
牛逼吧
第二种,通过数组来创建,
int[] numbers = {2, 3, 4, 5, 6};
int sum = Array.stream(numbers).sum();
这里它实际上返回的是一个特化流:IntStream,不然应该没有求和方法。
第三种是通过文件来创建流
因为我对文件操作还不是太了解,所以这里就简单提一下,
try(Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())){
//xxxx
}catch(xxxx){
//yyyy
}
第四种,通过函数来生成流,这是一种无限流,
Stream API 提供了两个静态方法来从函数生成硫,Stream.iterator, Stream.generate
1)迭代方法接受一个初始值,还有一个应用在每一个产生的新值上的表达式:
Stream.iterator(0, n-> n+2).limit(10).forEach(System.out::println());
接下来,作者给了一个生成斐波那契序列的例子,这里的关键就是要明白,入参可以是一个数组。
2)生成。和iterate方法类似,generate可以让你,按需生产一个无限流,
Stream.generate(Math::random).limit(5).forEach(System.out::println);
上面这个例子给的函数,是一个,无状态的,然后接下来做事还给了一个用匿名类,来实现有状态的流生成函数的例子,还是以上文提到的斐波那契序列为例。
如果这种内部带状态的,流处理函数不是一种好的实践,在实际编程中应该尽量少用,因为一旦带了内部的状态,以后就很难去做并行话处理。
- 《java编程思想》读书笔记(二)第五章(2)
成员初始化 Java尽力保证:所有变量在使用前都能得到恰当的初始化. 对于方法的局部变量,Java会以编译时报错的形式贯彻这种保证,比如: void f() { int i; //这里编译时就会报错, ...
- R in action读书笔记(2)-第五章:高级数据管理(下)
5.4 控制流 语句(statement)是一条单独的R语句或一组复合语句(包含在花括号{ } 中的一组R语 句,使用分号分隔): 条件(cond)是一条最终被解析为真(TRUE)或假(FAL ...
- R in action 读书笔记(1)--第五章:高级数据管理
5.2.1数学函数 函数 描述 abs(x) 绝对值 sqrt(x) 平方根 ceiling(x) 不小于x的最小整数 floor(x) 不大于x的最大整数 trunc(x) 向0的方向截取的X中的整 ...
- [读书笔记] R语言实战 (五) 高级数据管理
1. 数值函数 1) 数学函数 2) 统计函数 3. 数据标准化 scale() 函数对矩阵或者数据框的指定列进行均值为0,标准化为1的标准化 mydata <- data.frame(c1=c ...
- 读书笔记 - js高级程序设计 - 第五章 引用类型
引用类型 和 类 不是一个概念 用typeof来检测属性是否存在 typeof args.name == "string" 需要实验 访问属性的方法 .号和[] 一般情况下要 ...
- Spring实战第五章学习笔记————构建Spring Web应用程序
Spring实战第五章学习笔记----构建Spring Web应用程序 Spring MVC基于模型-视图-控制器(Model-View-Controller)模式实现,它能够构建像Spring框架那 ...
- 【读书笔记《Bootstrap 实战》】6.单页营销网站
我们已经掌握了很多实用 Bootstrap 的重要技能.现在,是时候拿出更多的创意来帮助客户实现他们全方位在线营销的愿望了.此次将带领大家做一个漂亮的单页高端营销网站. 主要任务如下: □ 一个大型 ...
- 《C#从现象到本质》读书笔记(九)第11章C#的数据结构
<C#从现象到本质>读书笔记(九)第11章C#的数据结构 C#中的数据结构可以分为两类:非泛型数据结构和泛型数据结构. 通常迭代器接口需要实现的方法有:1)hasNext,是否还有下一个元 ...
- 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...
- 《C#从现象到本质》读书笔记(八)第10章反射
<C#从现象到本质>读书笔记(八)第10章反射 个人感觉,反射其实就是为了能够在程序运行期间动态的加载一个外部的DLL集合,然后通过某种办法找到这个DLL集合中的某个空间下的某个类的某个成 ...
随机推荐
- Windows7双系统的启动顺序怎样修改?
本着工作的原因或个人的原因,不过绝大部分还是因为个人怀旧的因素比较多.大家即使安装了新的Windows 7,可是又不想放弃原来的xp765系统,安装双系统就成为不少人的选择.不过有一个麻烦,那就是系统 ...
- BZOJ3500 : PA2008 Cliquers
设g[i]表示n=i时的答案,则OEIS上可以找到如下递推式: g[i]=g[i-1]+g[i-2]-g[i-5]-g[i-7]+... 其中符号为++--交替,第i项为f[i],f[1]=1,f[2 ...
- Meta对照表
Http Content_type对照表: 文件扩展名 Content-Type(Mime-Type) 文件扩展名 Content-Type(Mime-Type) .*( 二进制流,不知道下载文件类型 ...
- android依据区域高度切割文本问题
android字体显示涉及例如以下參数:1. 基准点是baseline:2. Ascent是baseline之上至字符最高处的距离:3. Descent是baseline之下至字符最低处的距离.4. ...
- 【Go命令教程】3. go install
命令 go install 用于编译并安装指定的代码包及它们的依赖包.当指定的代码包的依赖包还没有被编译和安装时,该命令会先去处理依赖包.与 go build 命令一样,传给 go install 命 ...
- intel32指令中文版
http://scc.qibebt.cas.cn/docs/optimization/VTune(TM)%20User's%20Guide/mergedProjects/analyzer_ec/mer ...
- Unity3d学习笔记记录
1.发布到 ipad字体显示不出来,改变Position位置的Z轴为-1 2.发布打包有问题,记得用户权限有没有设置 3.ipad4分辨率:2048*1536 4.调整界面大小,尽量调整底下子对象位置 ...
- FreeCommander 学习手册
概述 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3470728.html FreeCommander(下文简称FC),是Windows下面比较强大的文 ...
- Android 中的概念大集合
Intent: An Intent is an object that provides runtime binding between separate components (such as tw ...
- SQL 参考
本主题将介绍 ArcGIS 中的选择表达式所用的常规查询的各个元素.ArcGIS 中的查询表达式使用常规 SQL 语法. 警告: SQL 语法不适用于使用字段计算器计算字段. 字段 在 SQL 表达式 ...