Java 9 中Stream API介绍
1. 概述
在这篇简短的文章中,我们将重点关注 Java 9 中新的有趣的 Stream API 改进。
2. Stream Takewhile/Dropwhile
StackOverflow 上反复出现了关于这些方法的讨论(最流行的是这个 )。 想象一下,我们想通过在前一个Stream的值上添加一个字符来生成一个String的Stream,直到这个Stream中的当前值的长度小于10。
我们将如何在 Java 8 中解决它?我们可以使用一个短路中间操作,例如limit ,allMatch 实际上用于其他目的,或者基于Spliterator 编写我们自己的takeWhile 实现,这反过来又使这样一个简单的问题复杂化。
使用 Java 9,解决方案很简单:
Stream<String> stream = Stream.iterate("", s -> s + "s")
.takeWhile(s -> s.length() < 10);
takeWhile操作接受一个Predicate ,该Predicate应用于元素以确定这些元素的最长前缀(如果流是有序的)或流元素的子集(如果流是无序的)。
为了继续前进,我们最好理解术语“最长前缀”和“Stream子集”的含义:
- 最长前缀是与给定谓词匹配的流元素的连续序列。序列的第一个元素是这个流的第一个元素,紧跟在序列最后一个元素之后的元素与给定的谓词不匹配
- Stream 的子集是Stream的一些(但不是全部)元素与给定谓词匹配的集合。
介绍完这些关键术语后,我们就可以轻松理解另一个新的dropWhile操作了。 它与takeWhile完全相反。如果流是有序的,则dropWile在删除与给定谓词匹配的元素的最长前缀后返回由该Stream的剩余元素组成的流。
否则,如果Stream是无序的,则dropWile在删除与给定谓词匹配的元素子集后返回由该Stream的剩余元素组成的流。
让我们使用前面获得的Stream丢弃前五个元素:
stream.dropWhile(s -> !s.contains("sssss"));
简单地说,dropWhile操作将删除元素,而给定的元素谓词返回true并停止删除第一个谓词的false。
3. 流迭代
下一个新特性是用于有限Stream生成的重载iterate方法**。不要与返回由某个函数产生的无限顺序有序Stream有限 变体混淆。 新的iterate通过添加适用于元素的谓词来稍微修改此方法,以确定 Stream 何时必须终止。它的使用非常方便简洁:
Stream.iterate(0, i -> i < 10, i -> i + 1)
.forEach(System.out::println);
它可以与相应的 for语句相关联:
for (int i = 0; i < 10; ++i) {
System.out.println(i);
}
4. StreamOfnullable
在某些情况下,我们需要将元素放入Stream中。有时,这个元素可能是null,但我们不希望Stream包含这样的值。它导致编写if语句或三元运算符来检查元素是否为null。
假设collection和map变量已经创建并填充成功,请看以下示例:
collection.stream()
.flatMap(s -> {
Integer temp = map.get(s);
return temp != null ? Stream.of(temp) : Stream.empty();
})
.collect(Collectors.toList());
为避免此类样板代码,已将 ofNullable 方法添加到Stream类中。使用这种方法,前面的示例可以简单地转换为:
collection.stream()
.flatMap(s -> Stream.ofNullable(map.get(s)))
.collect(Collectors.toList());