Java 9 Stream API 新增功能
本文聚焦Java 9 Stream API 新增功能。
1. Stream Takewhile/Dropwhile
假如我们需要生成字符串流,增加一个字符至前一个流的值,直到流当前值的长度小于10.
在java8中如何实现?需要使用短路的中间操作如,limit,allMatch(实际上用于其他目的)。或者基于Spliterator实现自己的takeWhile。总之,把简单问题复杂化。
Java9的实现非常简单:
Stream<String> stream = Stream.iterate("", s -> s + "s")
.takeWhile(s -> s.length() < 10);
takeWhile操作带一个Predicate参数,其应用于元素决定在所有元素中取最长的前缀(如果流是有序的),或者流所有元素的子集(流是无序的)。
继续学习之前最好理解“最长的前缀”和“流的子集”是什么意思:
-
最长的前缀:匹配条件的流中连续元素序列. 序列的第一个元素是流的第一个元素, 紧接在序列最后一个元素后面的元素与给定的谓词不匹配。
-
“流的子集:流中匹配条件的部分元素集合。
介绍完这些关键术语后,我们可以较容易地理解另一个新的dropWhile操作。
它恰好是takeWhile的相反操作,如果流是有序的,dropWhile返回的流,是删除了最长前缀后留下元素集合。如果流是无序的,dropWhile返回的流包括删除匹配条件的子集后留下元素的集合。
使用前缀获得流实现丢弃前五个元素:
stream.dropWhile(s -> !s.contains("sssss"));
简言之,dropWhile操作删除对于给定条件返回true的元素,并第一次遇到条件返回false停止删除。
2. Stream Iterate
接着介绍新特性是重载iterate方法实现有限流生成。不要与另一个重载static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
方法混淆,其返回有函数生成的无限顺序序列流。
新的iterate增加了一个predicate决定生成流什么条件必须终止,其使用很方便、简洁:
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);
}
3. Stream Ofnullable
有时添加至流中的元素可能为null,我们并不希望这样值存在流中。因此需要些if条件语句或三元运算符检查元素是否为null。
假如我们有collection 和 map 变量,内容如下:
List<String> collection = Arrays.asList("A", "B", "C");
Map<String, Integer> map = new HashMap<>() {
{
put("A", 10);
put("C", 30);
}
};
请看下面示例:
collection.stream()
.flatMap(s -> {
Integer temp = map.get(s);
return temp != null ? Stream.of(temp) : Stream.empty();
})
.collect(Collectors.toList());
这里需要判断temp是否为null,导致flatMap方法过于冗长。为了避免使用Stream类的ofNullable方法,相同功能代码非常简洁:
collection.stream()
.flatMap(s -> Stream.ofNullable(map.get(s)))
.collect(Collectors.toList());
4. 总结
本文介绍了Java 9 Stream Api中新增的方法,这些增强功能会帮助使用更少的代码实现强大功能。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/103650977