前言
Java 9 Stream API新增了 takeWhile
/ dropWhile
, ofNullable
,iterate
等方法。
我们通过例子来了解下它们。
正文
使用takeWhile()和dropWhile()方法对流进行限制
新的方法takeWhile
和dropWhile
允许我们根据谓词获取流的一部分。
这里的流可以是有序的,也可以是无序的,所以:
- 在一个有序的流上,
takeWhile
返回从流中取出的与给定谓词匹配的元素的“最长前缀”,从流的开头开始。 - 在一个无序流上,
takeWhile
从流的开头开始返回匹配给定谓词(但不是全部)的流元素的子集。
dropWhile
方法与takeWhile
方法相反。
- 在一个有序的流中,
dropWhile
返回与给定谓词匹配的“最长前缀”之后的剩余项。 - 在一个无序的流上,
dropWhile
在删除匹配给定谓词的元素子集后返回剩余的流元素。
takeWhile和dropWhile的例子
在本例中,我们有一个从’a’到’i’的字符List。我想要在迭代中获取出现在’d’之前的所有字符。
1 | List<String> alphabets = List.of("a", "b", "c", "d", "e", "f", "g", "h", "i"); |
如前所述,dropWhile
的作用与takeWhile
方法相反,因此在上面的例子中,如果使用dropWhile
方法,它将返回takeWhile
谓词所留下的所有字符。
1 | List<String> alphabets = List.of("a", "b", "c", "d", "e", "f", "g", "h", "i"); |
重载流的iterate方法
iterate()
方法,用于创建以单个元素(the seed)开始的流,并通过连续应用一元运算符生成后续元素,结果是一个无限的流。
要终止流,需要使用限制或其他一些短路函数,如findFirst
或findAny
。
Java 8中的iterate
方法有这样的签名:
1 | static Stream iterate(final T seed, final UnaryOperator f) |
在Java 9中,新的重载版本的iterate将一个谓词作为第二个参数:
1 | static Stream iterate(T seed, Predicate hasNext, UnaryOperator next) |
让我们看看Java 8和Java 9之间iterate
方法使用的不同之处。
iterate method in Java 8
1 | List<Integer> numbers = Stream.iterate(1, i -> i+1) |
iterate method in Java 9
1 | List<Integer> numbers = Stream.iterate(1, i -> i <= 10 ,i -> i+1) |
在上面的例子中,第一个流是使用带有限制的iterate
的Java 8方式。第二个使用谓词作为第二个参数。
新方法ofNullable()
在Java 8之前,流中不能有null
值。它会导致NullPointerException
。
在Java 9中,ofNullable
方法允许我们创建一个单元素流,该流包装一个值(如果不是null),或者是一个空流。
1 | Stream<String> stream = Stream.ofNullable("123"); |
这里,count
方法返回流中非空元素的数量。
从技术上讲,Stream.ofnullable()
与在流API上下文中使用null
条件检查非常相似。