# Java 9 `Stream` API 的改进

> 原文： [https://howtodoinjava.com/java9/stream-api-improvements/](https://howtodoinjava.com/java9/stream-api-improvements/)

通过示例了解[流](https://docs.oracle.com/javase/9/docs/api/java/util/stream/Stream.html) API（即`takeWhile`/`dropWhile`方法，`ofNullable`和`iterate`方法）中 Java 9 的新改进。

```java
Table of Contents

Limiting Stream with takeWhile() and dropWhile() methods
Overloaded Stream iterate method
New Stream ofNullable() method
```

## 使用`takeWhile()`和`dropWhile()`方法限制`Stream`

新方法`takeWhile`和`dropWhile`允许您基于谓词获取流的一部分。 这里的流可以是有序的也可以是无序的，所以：

1.  在有序流上，`takeWhile`返回流的“最长前缀”，其元素匹配给定谓词。
2.  在无序流上，`takeWhile`返回流的子集，从流的开头开始，其元素匹配给定谓词（但不是全部）。

`dropWhile`方法与`takeWhile`方法相反。

1.  在有序流上，`dropWhile`返回匹配给定谓词的“最长前缀”之后的其余项。
2.  在无序流上，`dropWhile`返回不匹配给定谓词的剩余的流元素。

#### `takeWhile`和`dropWhile`示例

在此示例中，我们具有从`a`到`i`的字符列表。 我希望所有可能在迭代中出现在字符`d`之前的字符。

```java
List<String> alphabets = List.of("a", "b", "c", "d", "e", "f", "g", "h", "i");

List<String> subset1 = alphabets
        .stream()
        .takeWhile(s -> !s.equals("d"))
        .collect(Collectors.toList());

System.out.println(subset1);

Output:

[a, b, c]

```

如前所述，`dropWhile`的作用与`takeWhile`方法相反，因此在上面的示例中，如果使用`dropWhile`，它将返回`takeWhile`谓词留下的所有字符。

```java
List<String> alphabets = List.of("a", "b", "c", "d", "e", "f", "g", "h", "i");

List<String> subset2 = alphabets
        .stream()
        .dropWhile(s -> !s.equals("d"))
        .collect(Collectors.toList());

System.out.println(subset2);

Output:

[d, e, f, g, h, i]

```

## 重载`Stream`迭代方法

`iterate()`方法用于创建以单个元素（种子）开头的流，并通过依次应用一元运算符来生成后续元素。 结果是无限的流。 为了终止流，使用限制或其他一些短路函数，例如`findFirst`或`findAny`。

Java 8 中的`iterate`方法具有签名：

```java
static Stream iterate(final T seed, final UnaryOperator f)
```

在 Java 9 中，新的`iterate`重载版本将谓词作为第二个参数：

```java
static Stream iterate(T seed, Predicate super T> hasNext, UnaryOperator next)
```

让我们看看从 Java 8 到 Java 9 的`iterate`方法的使用不同。

#### Java 8 中的迭代方法

```java
List<Integer> numbers = Stream.iterate(1, i -> i+1)
                            .limit(10)
                            .collect(Collectors.toList());

System.out.println(numbers);

Output:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

```

#### Java 9 中的迭代方法

```java
List<Integer> numbers = Stream.iterate(1, i -> i <= 10 ,i -> i+1)
                                .collect(Collectors.toList());

System.out.println(numbers);

Output:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

```

在上面的示例中，第一个流是 Java 8 使用限制迭代的方式。 第二个使用谓词作为第二个参数。

## 新的`Stream ofNullable()`方法

在 Java 8 之前，流中不能具有`null`值。 会导致`NullPointerException`。

在 Java 9 中，`ofNullable`方法使您可以创建**单元素流**，该流将包装一个值（如果不为`null`），否则为空流。

```java
Stream<String> stream = Stream.ofNullable("123");
System.out.println(stream.count());

stream = Stream.ofNullable(null);
System.out.println(stream.count());

Output:

1
0

```

此处，`count`方法返回流中非空元素的数量。

从技术上说，`Stream.ofNullable()`与流条件上下文中的空条件检查非常相似。

将我的问题放在评论部分。

学习愉快！