JAVA 8函数式编程(六):怎样复用Stream对象
来源:互联网 发布:北京it外包 编辑:程序博客网 时间:2024/06/06 16:24
在JAVA 8的Stream方法中,分为两大类,一类是惰性求值,另一类是立刻求值,只要Stream调用了立刻求值,Stream就会自动关闭,如果再次调用,将会提示如下错误:
java.lang.IllegalStateException: stream has already been operated upon or closed at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229) at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479) at com.mirana.stream.FlatMapReduceTest.testFlatMap(FlatMapReduceTest.java:49) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498)
这样的情况,就给我们摆出了一个难题,如果我们既要进行元素个数统计,又要对元素进行求和,两个立刻求值的函数,必然只能执行一个,怎么办呢?
查遍了Stream的官方接口,发现并没有解决此问题的方法,但是我们可以采用封装的方式解决此问题,即通过调用函数来获取新的Stream对象,从而分离Stream实例,如下:
private List<String> joins = Lists.newArrayList("1, 2, 3", "2, 3, 4", "3, 4, 5");// 通过函数每次返回新的Stream对象public Stream<Integer> getStream() { // 将字符转换为数字Stream return joins.stream().flatMap(str -> { String[] nums = str.split(","); // 将字符转换为数字 return Arrays.asList(nums).stream().map(num -> { return Integer.parseInt(num.trim()); }); });}
从上面的例子可以看出:
1. Stream并没有依赖于可迭代对象的并发锁,只要调用stream()方法就会新的Stream实例,如上例中的joins对象可多次创建Stream实例,实例之间并没有相互影响;
2. flatMap方法与map方法的区别在于函数接口的返回值(注意,是函数接口,而不是方法自身,即Function.apply方法),flatMap必须返回Stream,而Map没有此限制;
如果要在函数内定义内调用,上述的方法还可以采用lambda的样式,如下:
@Testpublic void testReStream() { // 直接在函数内定义函数 Supplier<Stream<Integer>> supplier = () -> joins.stream().flatMap(str -> { String[] nums = str.split(","); return Arrays.asList(nums).stream().map(num -> { return Integer.parseInt(num.trim()); }); }); // 计数 assertThat(supplier.get().count(), IsEqual.equalTo(9L)); // 求和 int sum = supplier.get().reduce((a, b) -> a + b).get(); assertThat(sum, IsEqual.equalTo(27));}
结论
JAVA 8的Stream类并没有直接提供复用的方法,只能采用封装的方式进行复用,所以也只是代码的复用,性能并没有提升。
阅读全文
0 0
- JAVA 8函数式编程(六):怎样复用Stream对象
- Java8函数式编程之六 :Stream (流)介绍
- java函数式编程之Stream
- Java 8函数式编程笔记(二)- 集合和流(stream)
- 函数式编程----stream.js
- Stream API函数式编程
- JAVA 函数式编程学习之Stream API
- java 8(二)--函数式数据处理Stream
- Java函数式编程(六)查找元素
- angular2系列教程(六)两种pipe:函数式编程与面向对象编程
- Java1.8新特性 Lambda/Stream/函数式编程
- 【转】JAVA8-Stream弥补函数式编程
- 函数式编程 流Stream的使用
- Java Stream(8)(Stream完结)
- Java并发编程(六)不可改变对象
- Java 8新特性 Stream API 编程
- JAVA 8函数式编程(二):每个函数都是可以传递的对象
- 【Java没基础】函数式编程——Stream API 中的收集器
- course 系统
- BeanUtils.populate的作用
- 图像特效之老照片
- ubuntu下latex的使用
- 宏以及#define;enum;comst的区别
- JAVA 8函数式编程(六):怎样复用Stream对象
- rbac权限管理初学
- C语言存储类
- mysql导出数据时提示错误1290(secure_file_priv)的解决办法
- POJ 1995 Raising Modulo Numbers(快速幂取模)
- java 字符串截取的几种方式
- [转]图像边缘提取-Canny算法
- 纯净:Linux目录结构
- JVM的内存分配