Java就业课程Stream流(13)完结

第一章 常用函数式接口
Predicate接口
有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用
java.util.function.Predicate 接口。
Predicate 接口中包含一个抽象方法: boolean test(T t) 。

默认方法:and
既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个 Predicate 条件使用“与”逻辑连接起来实
现“并且”的效果时,可以使用default方法 and 。其JDK源码为:

default Predicate<T> and(Predicate<? super T> other) {
     Objects.requireNonNull(other);
           return (t) ‐> test(t) && other.test(t);
}

默认方法:or
与 and 的“与”类似,默认方法 or 实现逻辑关系中的“或”。JDK源码为:

default Predicate<T> or(Predicate<? super T> other) {
      Objects.requireNonNull(other);
           return (t) ‐> test(t) || other.test(t);
}

默认方法:negate
“与”、“或”已经了解了,剩下的“非”(取反)也会简单。默认方法 negate 的JDK源代码为: default

Predicate<T> negate() {
     return (t) ‐> !test(t);
  }

Function接口
java.util.function.Function<T,R> 接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。有进有出,所以称为“函数Function”。

抽象方法:apply
Function 接口中最主要的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。使用的场景例如: 将 String 类型转换为 Integer 类型。

默认方法:andThen
Function 接口中有一个默认的 andThen 方法,用来进行组合操作。JDK源代码如:

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
      Objects.requireNonNull(after);
           return (T t) ‐> after.apply(apply(t));
}

请注意,Function的前置条件泛型和后置条件泛型可以相同。

第二章Stream流

循环遍历的弊端: 为什么使用循环?因为要进行遍历。但循环是遍历的唯一方式吗?遍历是指每一个元素逐一进行处理,而并不是从第一个到最后一个顺次处理的循环。前者是目的,后者是方式。

无关逻辑方式的语义:获取流、过滤姓张、过滤长度、逐一打印。代码中并没有体现使用线性循环或是其他任何算法进行遍历,我们真正要做的事情内容被更好地体现在代码中。

这里的 filter过滤 、 map 映射、 skip跳过 都是在对函数模型进行操作,集合元素并没有真正被处理。只有当终结方法 count执行的时候,整个模型才会按照指定策略执行操作。而这得益于Lambda的延迟执行特性。
备注:“Stream流”其实是一个集合元素的函数模型,它并不是集合,也不是数据结构,其本身并不存储任何元素(或其地址值)。

Stream流特点:
1.Stream流是单向的,不能重复使用 重要
2.Stream流具有延迟性(首先拼好一个“模型”步骤方案,然后再按照方案去执行它。并且方案中一定要有终结的方法) 重要
3.Stream流不会更改数据源

Stream(流)是一个来自数据源的元素队列并支持聚合操作
元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等

聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluentstyle)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。

内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

获取流
java.util.stream.Stream 是Java 8新加入的最常用的流接口。(这并不是一个函数式接口。)
获取一个流非常简单,有以下几种常用的方式:
所有的 Collection 集合都可以通过 stream 默认方法获取流;
Stream 接口的静态方法 of 可以获取数组对应的流。

根据Collection获取流
首先, java.util.Collection 接口中加入了default方法 stream 用来获取流,所以其所有实现类均可获取流

根据Map获取流
java.util.Map 接口不是 Collection 的子接口,且其K-V数据结构不符合流元素的单一特征,所以获取对应的流需要分key、value或entry等情况:

常用方法
终结方法:返回值类型不再是 Stream 接口自身类型的方法,因此不再支持类似 StringBuilder 那样的链式调用。本小节中,终结方法包括 count 和 forEach 方法。
延迟方法:返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方法均为延迟方法。)

过滤:filter 延迟方法
可以通过 filter 方法将一个流转换成另一个子集流。方法签名:
Stream filter(Predicate<? super T> predicate);

复习Predicate接口
此前我们已经学习过 java.util.stream.Predicate 函数式接口,其中唯一的抽象方法为:
boolean test(T t);

统计个数:count 终结方法
正如旧集合 Collection 当中的 size 方法一样,流提供 count 方法来数一数其中的元素个数: long count(); 该方法返回一个long值代表元素个数(不再像旧集合那样是int值)

逐一处理:forEach 终结方法
void forEach(Consumer<? super T> action);该方法并不保证元素的逐一消费动作在流中是被有序执行的。该方法接收一个Consumer接口函数,会将每一个流元素交给该函数进行处理

取用前几个:limit 延迟方法
limit方法可以对流进行截取,只取用前n个。方法签名:Stream limit(long maxSize);
参数是一个long型,如果集合当前长度大于参数则进行截取;否则不进行操作。

跳过前几个:skip 延迟方法
如果希望跳过前几个元素,可以使用skip方法获取一个截取之后的新流:
Stream skip(long n);如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流。

映射:map
如果需要将流中的元素映射到另一个流中,可以使用map方法。方法签名:
Stream map(Function<? super T, ? extends R> mapper);该接口需要一个Function函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流

复习Function接口
此前我们已经学习过 java.util.stream.Function 函数式接口,其中唯一的抽象方法为:
R apply(T t);

组合:concat
如果有两个流,希望合并成为一个流,那么可以使用 Stream 接口的静态方法 concat :
static Stream concat(Stream<? extends T> a, Stream<? extends T> b)

第三章扩展知识点

转换为并发流
Stream 的父接口 java.util.stream.BaseStream 中定义了一个 parallel 方法: S parallel();

直接获取并发流
在通过集合获取流时,也可以直接调用 parallelStream 方法来直接获取支持并发操作的流。方法定义为: default Stream parallelStream() {…}

收集Stream结果
收集到集合中Stream流提供 collect 方法,其参数需要一个 java.util.stream.Collector<T,A, R> 接口对象来指定收集到哪种集合中。幸运的是, java.util.stream.Collectors 类提供一些方法,可以作为 Collector 接口的实例:

public static Collector<T, ?, List> toList() :转换为 List 集合。
public static Collector<T, ?, Set> toSet() :转换为 Set 集合。

收集到数组中
Stream提供 toArray 方法来将结果放到一个数组中,由于泛型擦除的原因,返回值类型是Object[]的: Object[] toArray();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值