0%

Stream 提供的一系列方法,在经过中间操作之后,最后还是为了得到确定的元素。因此,Stream 还提供了大量的终止操作,以便我们能得到想到的数据。

三个 Match 操作

方法定义

boolean allMatch(Predicate<? super T> predicate)
boolean anyMatch(Predicate<? super T> predicate)
boolean noneMatch(Predicate<? super T> predicate)

*Match 方法有三个:allMatch 表示所有元素都要通过 Predicate 的考验,anyMatch 表示只要有任何一个元素通过考验就行,noneMatch 表示没有任何一个掉进 Predicate 的陷阱才可以。

看起来是不是有些熟悉?没错,是有点像 &&||! 的条件表达式。

阅读全文 »

提到著名的 NullPointerException,相信大家都熟悉。空指针异常不单单经常出现在我们的测试环境的代码里,在生产环境其实也不少见。而为了尽可能的避免空指针异常的出现,我们更是小心翼翼地在代码加各种判断。

Java8 则引入了一个新的类 Optional,可以有效的避免我们一不小心就写了 NPE 的代码。

先看源码

源码节选,有省略,基于 Java8。(Java9 之后有增强)

阅读全文 »

Stream 操作过程中,有可能会对元素进行排序,这点 Stream 支持的也不输集合。考虑到流内操作只有在终止操作时才会触发导致不便调试,Stream 也提供了偷窃利器 peek 来方便我们调试。

sorted

方法定义

Stream<T> sorted();

Stream<T> sorted(Comparator<? super T> comparator);

sorted 提供了两个方法,一个无参,一个需要传入比较器。两种方法运行过后,都可以将流内的元素排序。

使用举例

根据文档来看,sorted() 会将流内的元素进行自然排序,同时要求元素必须实现 Comparable 接口。看到这里,问题就来了,什么是自然排序?为什么要实现 Comparable 接口?我们来实验一下。

阅读全文 »

map 操作算是比较常用的操作了,它可以将元素经过处理后输出成另一个元素。这就和 java method 很像了,输入参数,经过方法处理,输出一个返回参数。

map

方法定义

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

map 方法看起来就很简洁明了,入参是 Function,作用是将元素 T 经过逻辑处理后转换成 R。当然,这个转换过程中可做的东西就多了。比如类型转换、属性提取、逻辑运算、业务处理等。

stream map 转换

阅读全文 »

Stream 流的数据处理过程中,少不的一点就是对数据的筛选。在以前的编程方式里,对集合数据的筛选,要经过遍历、判断,搞不好过程中再遇到个异常,比如边遍历边 remove。而 Stream 提供的数据筛选方法,简化我们写法的同时,也可以有效避免复杂编码过程中不经意间写的 bug。

filter

方法定义

Stream<T> filter(Predicate<? super T> predicate);

filter 方法,通过传入的 Predicate 对流内的元素进行过滤,可以将不满足条件的元素过滤掉。

关于 Predicate ,我们也在函数式接口的内容里讲过:传送门

阅读全文 »

Stream 的创建,Stream 接口本身提供了一些方法来完成这个操作。而除此之外,JDK 本身也提供了其他类来完成这个操作。考虑到 Stream 的集合息息相关,合理猜测 ArraysCollectionMap 可能会提供创建 stream 的方法。但 Stream<T> 只有单泛型,而 Map<K,V> 是键值对,目测 Map 中不含有 Stream 相关的方法。来,大家可以看源码验证一下。

通过查看 JDK 源码发现, ArraysCollection 均提供 stream 相关的方法,而 Map 并未提供对应的方法。

阅读全文 »

看完了 lambda,是时候了解下 stream 了。到这里,我们的第二位主角终于登场了。Java8 推出这个极具实用性的 stream

黄四郎:Stream,Java8 用的 stream。Stream,You know?

马邦德:Stream,流,文件操作用的!

黄四郎:你看看这位师爷就是装糊涂的高手,Stream,说成操作文件的,那 IO 是什么?

马邦德:流,Java8 stream,提供集合便捷操作的。

阅读全文 »

lambda 表达式和函数式接口给我们的编码在一定程度上提供了便利,但我们在使用的时候也要尽量优雅的使用,达到最佳实践。

lambda 表达式结构

在第一章节,我们有提到,lambda 表达式的结构大致为:(类型)(参数1, 参数2, …) -> {方法实现}。

  1. lambda 表达式返回类型能不写则不写
  2. 参数类型尽可能不写
  3. 单参数时,不写小括号
  4. 单行表达式体,不写大括号和 return 关键字
  5. 能直接使用方法引用时,直接使用方法引用
    阅读全文 »