您的位置:首页 > Web前端

Java 8 Stream API Features Intermediate operations & Terminal operations

2016-12-15 15:33 477 查看
Stream API 中提供了findFirst(),orElse() 这样的 method, 这些 method 具体是做什么,可以看看文档:一目了然。

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java8