文章目录
Java 8 中对核心类库的改进主要包括集合类的 API 和新引入的流 (Stream)。流使程序员得以站在更高的抽象层次上对集合进行操作。
迭代
从外部迭代到内部迭代。
外部迭代
首先调用 iterator 方法,产生一个新的 Iterator 对象,进而控制整个迭代过程,这就是外部迭代。
迭代过程通过显式调用 Iterator 对象的 hasNext 和 next 方法完成迭代。
for 循环其实是一个封装了迭代的语法糖。
内部迭代
stream() 方法的调用,该方法不是返回一个控制迭代的 Iterator 对象,而是返 回内部迭代中的相应接口:Stream。
使用stream() 方法,就是内部迭代。
实现机制
long count = list.stream().filter(e -> e.getName().equals("a")).count();
这行代码并未做什么实际性的工作,filter 只刻画出了 Stream,但没有产生新的集合。
像 filter 这样只描述 Stream,最终不产生新集合的方法叫作惰性求值方法;而像 count 这样 最终会从 Stream 产生值的方法叫作及早求值方法。
判断一个操作是惰性求值还是及早求值?
只需看它的返回值。如果返回值是 Stream, 那么是惰性求值;
如果返回值是另一个值或为空,那么就是及早求值。
使用这些操作的理想方式就是形成一个惰性求值的链,最后用一个及早求值的操作返回想要的结果,这正是它的合理之处。计数的示例也是这样运行的,但这只是最简单的情况:只含两步操作。
常用的流方法
具体的可以看下Stream类中的方法。
collect(toList())
collect(toList()) 方法由 Stream 里的值生成一个列表,是一个及早求值操作。
List<String> collected = Stream.of("a", "b", "c").collect(Collectors.toList());
这段程序展示了如何使用 collect(toList()) 方法从 Stream 中生成一个列表。
map
如果有一个函数可以将一种类型的值转换成另外一种类型,map 操作就可以 使用该函数,将一个流中的值转换成一个新的流。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class MapTest {
public static void main(String[] args) {
List<String> collected = new ArrayList<>();
for (String string : Arrays.asList("a", "b", "hello")) {
String uppercaseString = string.toUpperCase();
collected.add(uppercaseString);
}
System.out.println(collected);
List<String> collected1 = Stream.of("a", "b", "hello")
.map(e -> e.toUpperCase())