首页 > 代码库 > Java8 Stream API

Java8 Stream API

Stream是Java8中,操作集合的一个重要特性。

  • 从iteration到Stream操作

当你操作一个集合的时候,你通常的做法是迭代每一个元素,然后处理你想要的事情。举个例子:

String contents = new String(Files.readAllBytes(    Paths.get("alice.txt")), StandardCharsets.UTF_8);  // 读取文件到字符串中List<String> words = Arrays.asList(contents.split("[\\P{L}]+"));  // 截取words

现在我们来迭代操作它:

int count=0;for (String w : words) {    if (w.length() > 12) count++;}

这段代码有什么问题吗?除了并行处理不是很好以为我想是没有。在Java8中,相同的操作是这么处理的:

long count = words.stream().filter(w -> w.length() > 12).count();

so cool!从代码中,我们就能非常容易的看出它要表达的意思,filter是针对words的过滤。

有人会问,这样的操作的确让人很是兴奋,但是刚才说到的并行处理它能解决吗?答案是不可以,但是Java8给我们提供了非常好的API,并行处理如下:

long count = words.parallelStream().filter(w -> w.length() > 12).count();

通过将stream()修改为parallelStream(),这样就可以并行的进行过滤和统计了。

 从表面上,stream看起来和集合很像,你可以自由的操作它。但是有以下几点不同:

  1. stream不存储集合元素
  2. stream操作不修改源数据,他们是返回一个新的streams来承载结果
  3. stream操作都会尽可能的进行延迟加载。这意味着当需要使用结果的时候它才会才运行。

当你使用stream的时候,需要关注一下3个阶段:

  1. 创建一个stream
  2. 指定的中间操作将初始stream转化为其他stream
  3. 最终的操作会产生一个结果,在调用最终操作前都会延迟执行的。在这之后,stream不会再被使用。

在上面的例子中,stream()和parallelStream()创造了stream,filter方法转化了它,count方法是最终的操作。


注意:stream操作不是按照引用的顺序来执行的。在例子中,知道count调用才执行。当count方法请求第一个元素,filter方法开始请求元素,知道找到一个长度大于12的元素。

 


 

  • Stream创建

Java8中,你就可以将集合的操作都利用stream来处理,如果你有一个数组,使用静态的Stream.of方法来实现:

// 分隔后返回String[]Stream<String> words = Stream.of(content.split("[\\P{L}]+"));

of方法定义:

public static<T> Stream<T> of(T t);public static<T> Stream<T> of(T... values);

所以你可以构造很多参数的stream。

使用Arrays.stream(array, from, to),可以得到数组的一部分。

想要创建一个空的stream,可以使用Stream.empty方法:

Stream<String> silence = Stream.empty();

stream接口有2个静态方法来构造无限的streams。generate方法是通过无参函数的。比如:

Stream<String> echos = Stream.generate(() -> "Echo");orStream<Double> randoms = Stream.generate(Math::random);

如果想要产生一个无限的序列,例如:0 1 2 3 ...,可以使用iterate方法来实现:

Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE));
  • filter.map和flatMap方法

待续,有没有期待?