原文: https://beginnersbook.com/2018/06/java-9-stream-api-enhancements/

我们已经了解到 Java 8 引入了流 API 以及其他一些很酷的功能。如果您不熟悉流,请参阅本指南:Java 8 - 流 API。Java 9 为流 API 引入了四种新方法。这些方法添加在java.util.Stream接口中。

Java 9 - 流 API 改进

Java 9 在流中添加了以下四种方法。由于Stream是一个接口,添加到它的方法是默认的和静态的。这是因为 java 8 允许我们在接口中使用默认和静态方法

  1. dropWhile() - 默认方法
  2. takeWhile() - 默认方法
  3. iterate() - 静态方法
  4. ofNullable() - 静态方法

Java 9 - Stream dropWhile()方法

方法dropWhile()删除流的所有元素,直到给定的谓词失败。

例如:

  1. jshell> Stream<Integer> mystream = Stream.of(11, 22, 40, 60, 100)
  2. mystream ==> [email protected]
  3. jshell> mystream.dropWhile(num -> num < 50).forEach(num -> System.out.println(num))
  4. 60
  5. 100

Java 9 - 流 API 改进 - 图1

注意:当流是无序的时,dropWhile()会丢弃所有元素,直到给定的谓词失败,一旦谓词失败,此方法不会检查流的其他元素。这意味着结果流可能具有与谓词匹配的元素,让我们举一个例子来理解这一点。

  1. jshell> Stream<Integer> mystream = Stream.of(11, 22, 40, 60, 10, 15, 30, 100)
  2. mystream ==> [email protected]
  3. jshell> mystream.dropWhile(num -> num < 50).forEach(num -> System.out.println(num))
  4. 60
  5. 10
  6. 15
  7. 30
  8. 100

这里,元素 60 之后的流中存在的元素10,15,30与谓词匹配但是它们没有被dropWhile()删除,因为当谓词在元素 60 上失败时,该方法没有检查其他元素。

Java 9 - 流 API 改进 - 图2

Java 9 - Stream takeWhile()方法

方法takeWhile()dropWhile()方法相反。此方法在结果流中获取流的所有元素,直到谓词失败。简而言之,当谓词失败时,它会丢弃该元素以及流中该元素之后的所有元素。让我们举几个例子来理解这一点。

这里对有序流使用takeWhile()方法对流进行排序,takeWhile()方法获取所有元素,直到谓词在元素值 60 处失败。

  1. jshell> Stream<Integer> mystream = Stream.of(10, 20, 30, 40, 60, 90, 120)
  2. mystream ==> [email protected]
  3. jshell> mystream.takeWhile(num -> num < 50).forEach(num -> System.out.println(num))
  4. 10
  5. 20
  6. 30
  7. 40

对无序流使用takeWhile()方法与dropWhile()方法类似,一旦谓词失败,此方法也不会进一步检查元素。这就是元素 10 和 15 被丢弃的原因,因为它们位于元素 60 之后(谓词失败)。

  1. jshell> Stream<Integer> mystream = Stream.of(10, 20, 40, 60, 70, 10, 15, 100)
  2. mystream ==> [email protected]
  3. jshell> mystream.takeWhile(num -> num < 50).forEach(num -> System.out.println(num))
  4. 10
  5. 20
  6. 40

Java 9 - Stream iterate()方法

Java 9 中的iterate方法有三个参数。
第一个参数是初始化值,返回的流以此值开始。
第二个参数是谓词,迭代继续,直到这个给定的谓词返回false
第三个参数更新上一次迭代的值。

示例:在此示例中,第一个参数为 1.流以元素 1 开头。

num -> num < 30是第二个参数,它是一个谓词。迭代继续,直到返回falsenum -> num * 3是更新从上一次迭代返回的值的第三个参数。这类似于循环的计数器变量。

  1. jshell> IntStream.iterate(1, num -> num < 30, num -> num*3).forEach(num ->System.out.println(num))
  2. 1
  3. 3
  4. 9
  5. 27

从值 1 开始,我们将返回值乘以 3,这将一直持续到返回值大于 30。

Java 9 - 流 API 改进 - 图3

Java 9 - Stream ofNullable()方法

引入此方法是为了避免NullPointerException。如果流为null,则此方法返回空流。它也可以在非空流上使用,返回单个元素的顺序流。

空流示例

  1. jshell> Stream<String> stream = Stream.ofNullable(null)
  2. stream ==> [email protected]
  3. jshell> stream.forEach(str -> System.out.println(str))
  4. jshell>

Java 9 - 流 API 改进 - 图4

非空流示例

  1. jshell> Stream<String> stream = Stream.ofNullable("Rose")
  2. stream ==> [email protected]
  3. jshell> stream.forEach(str -> System.out.println(str))
  4. Rose
  5. jshell>

这些是在 Java SE 9 中完成的四种流 API 增强功能。