Java 8 Stream API Features Intermediate operations & Terminal operations
2016-12-15 15:33
477 查看
Stream API 中提供了findFirst(),orElse() 这样的 method, 这些 method 具体是做什么,可以看看文档:一目了然。
findFirst(): 它是一个 terminal operator
orElse():
这里举这个 demo 是想说明什么问题呢,现在说 Java 比之前更 efficient ,为什么这么说呢,一点一点分析:我们 demo 示例里的 code 如果我们用 jdk1.7 来实现是这样的:
两次 output 是相同的。
如果从表面上看,jdk1.7的 implementation 看上去好像比 Stream API 的 efficient 要高一点,因为 jdk1.7里第一个 value 满足条件后就直接 break 了,而 Stream API里呢,它是要先把所有的 number 都检查一遍,看能不能被5整除,再都乘以2,最后再去取第一个,如果找不到就是输出0. 反了? 真的是这样么? Stream API 反而让 Java 的 efficient 变低了,哈哈,不要被表面给欺骗了。其实不是这样的。Stream API
不会这么愚蠢的,可是从 code 上面看,java code 从上而下编译执行,应该就是像我刚说的那样很笨的 execute 才对,现在去推翻它。我们给上面的代码加点东西:
看最终输出的:
in isDvs: 33
in isDvs: 44
in isDvs: 55
in mapDouble: 55
110
看到了吧,也是一样的,找到第一个满足条件的 number 后就不会再去往后面找了。很清楚吧。
解释一下:
我觉得下面这段英文解释的非常到位:
A stream supports two types of operations:
Intermediate operations
Terminal operations
Intermediate operations are also called lazy operations.
Terminal operations are also called eager operations.
A lazy operation does not process the elements until an eager operation is called on the stream.
An intermediate operation on a stream produces another stream.
Streams link operations to create a stream pipeline.
所以:
In the above code filter() and map() are all lazy operations. While reduce() is eager operation.
Stream API 的efficient 是要比 jdk1.7要高的,而且上面的 code 中使用的internal iteration,所以你 get 到 主要的 point 了么?
更多请参考这里: http://docs.oracle.com/javase/8/docs/api/ http://www.java2s.com/Tutorials/Java_Streams/Tutorial/Streams/Intermediate_operations_Terminal_operations.htm
public static void main(String... args){ List<Integer> values = Arrays.asList(11,22,33,44,55,60,75); System.out.println(values.stream() .filter(i -> i%5 == 0) .map(i -> i*2) .findFirst() .orElse(0) ); }
findFirst(): 它是一个 terminal operator
/** * Returns an {@link Optional} describing the first element of this stream, * or an empty {@code Optional} if the stream is empty. If the stream has * no encounter order, then any element may be returned. * * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * terminal operation</a>. * * @return an {@code Optional} describing the first element of this stream, * or an empty {@code Optional} if the stream is empty * @throws NullPointerException if the element selected is null */ Optional<T> findFirst();
orElse():
/** * Return the value if present, otherwise return {@code other}. * * @param other the value to be returned if there is no value present, may * be null * @return the value, if present, otherwise {@code other} */ public T orElse(T other) { return value != null ? value : other; }
这里举这个 demo 是想说明什么问题呢,现在说 Java 比之前更 efficient ,为什么这么说呢,一点一点分析:我们 demo 示例里的 code 如果我们用 jdk1.7 来实现是这样的:
public static void main(String... args){ List<Integer> values = Arrays.asList(11,22,33,44,55,60,75); System.out.println(values.stream() .filter(i -> i%5 == 0) .map(i -> i*2) .findFirst() .orElse(0) ); int result = 0; for (int i: values) { if(i % 5 == 0){ result = i*2; break; } } System.out.println(result); }
两次 output 是相同的。
如果从表面上看,jdk1.7的 implementation 看上去好像比 Stream API 的 efficient 要高一点,因为 jdk1.7里第一个 value 满足条件后就直接 break 了,而 Stream API里呢,它是要先把所有的 number 都检查一遍,看能不能被5整除,再都乘以2,最后再去取第一个,如果找不到就是输出0. 反了? 真的是这样么? Stream API 反而让 Java 的 efficient 变低了,哈哈,不要被表面给欺骗了。其实不是这样的。Stream API
不会这么愚蠢的,可是从 code 上面看,java code 从上而下编译执行,应该就是像我刚说的那样很笨的 execute 才对,现在去推翻它。我们给上面的代码加点东西:
public static void main(String... args){ List<Integer> values = Arrays.asList(11,22,33,44,55,60,75); System.out.println(values.stream() .filter(Java8Demo::isDivisible) .map(Java8Demo::mapDouble) .findFirst() .orElse(0) ); } public static boolean isDivisible(int i){ System.out.println("in isDvs: " + i); return i % 5 == 0; } public static int mapDouble(int i){ System.out.println("in mapDouble: " + i); return i * 2; }
看最终输出的:
in isDvs: 33
in isDvs: 44
in isDvs: 55
in mapDouble: 55
110
看到了吧,也是一样的,找到第一个满足条件的 number 后就不会再去往后面找了。很清楚吧。
解释一下:
我觉得下面这段英文解释的非常到位:
A stream supports two types of operations:
Intermediate operations
Terminal operations
Intermediate operations are also called lazy operations.
Terminal operations are also called eager operations.
A lazy operation does not process the elements until an eager operation is called on the stream.
An intermediate operation on a stream produces another stream.
Streams link operations to create a stream pipeline.
所以:
In the above code filter() and map() are all lazy operations. While reduce() is eager operation.
Stream API 的efficient 是要比 jdk1.7要高的,而且上面的 code 中使用的internal iteration,所以你 get 到 主要的 point 了么?
更多请参考这里: http://docs.oracle.com/javase/8/docs/api/ http://www.java2s.com/Tutorials/Java_Streams/Tutorial/Streams/Intermediate_operations_Terminal_operations.htm
相关文章推荐
- Java 8 Stream API features --- filter/reduce & predicate Interface test method
- Java 8 Stream API features --- map/reduce methods
- memcached java && python client api 共享
- java jdk & java api 帮助文档(中文、英文版)
- <java——常用对象API、其他对象>
- JAVA学习第三十一课(常用对象API)- StringBuffer类&&StringBuilder类
- java api
- 相对路径获取JAVA配置文件Class.getResourceAsStream() & ClassLoader的getResourceAsStream()
- Java8学习:Lambda表达式、Stream API和功能性接口 — 教程、资源、书籍和实例
- JAVA-API Dom4J解析xml/OPML & Rome解析RSS & QRCode编码解码
- (转)JavaMail(JAVA邮件服务) API…
- [Java 8] (7) 利用Stream类型的"懒"操作
- 使用Java StAX API(XML Stream Process API)写的XMLParser
- (转->作者:陈光耀 )Java调用Ant API用法收集
- java jdk & java api 帮助文档(中文、英文版)
- apache-karaf-3.0.0发布features,出现"java.io.IOException: Error resolving artifact"异常解决
- Could not load 'clearsilver-jni' java.library.path = out/host/linux-x86/lib make: *** [out/target/common/docs/api-stubs-timestam
- java jdk & java api 帮助文档(中文、英文版)
- Java笔记4 JavaAPI<2>TreeSet、Comparator、泛型
- 【JAVA学习】读取文件getClassLoader().getResourceAsStream("xxx")