Java8 stream 流的基本操作

  流提供了一种让我们可以在比集合更高的概念级别上指定计算的数据视图。通过使用流,我们可以说明想要完成什么任务,而不是说明如何去实现它。我们将操作的调度留给具体实现去解决。

演示类(The demo class)

1
2
3
4
5
6
7
8
9
10
11
public class Person{
private final String name;
private final boolean gender;

public Person(String name,boolean gender){
this.name = name;
this.gender = gender;
}
//getters and setters
//...
}

需求:在一个List persons 中找出所有的男性,并打印其姓名

在Java8以前,我们通常是用foreach遍历实现这样的需求

但在Java8中,我们可以这样写

1
2
3
4
persons.stream()
.filter(Person:getGender)
.map(Person:getName)
.forEach(a->System.out.println(a));

流的使用

  这个工作流是操作流时的典型流程。

  • 创建一个流
  • 指定将初始流转换为其他流的中间操作,可能包含多个步骤
  • 应用终止操作,从而产生结果。这个操作会强制执行之前的惰性操作。从此之后,这个流就在也不能使用了(mark:一个流只能使用一次)

    流的创建

    从数组创建
    1
    Stream<Stream> words = Stream.of("hello,stream".split(""));

of 方法具有可变长的参数,因此我们可以构建具有任意数量引员的流

1
Stream<Stream> coderWords = Stream.of("java","python","c","scala");

使用ArrayS.stream(array,from,to)可以从数组中位于from(包括)和to(不包括)的元素中创建一个流

从集合创建

Collectionstream()parallelStream(),意味着所有实现Collection的集合都可以使用这两个方法来创建一个流,见演示

  • 自己创建流
    • 创建不包含任何元素的流
      1
      Stream<String> silence = Stream.empty();
+ `genetate`产生无限流
1
2
Stream<String> echos = Stream.generate(()->"Echo");//常量值流
Stream<Double> randoms = Stream.generate(Math::random);//随机数流
+ `iterate`产生无限流
1
Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO,n->n.add(BigInteger.ONE));//迭代增加,产生0 1 2 3 ...
中间操作
filter

filter过滤流,很形象贴切

1
2
List<String> wordList = ...;
Stream<String> words = wordList.stream().filter(w->w.length()>12);

map

按照某种方式转换流

1
2
Stream<String> lowerCaseWords =
words.stream().map(String::toLowerCase);

flatMap

获取摊平的流

1
2
3
4
Stream<Stream<String>> result =
words.stream().map(a->letters(a));
Stream<String> flatResult =
words.stream().flatMap(a->letters(a));

limit,skip,concat,distinct,sorted,peek
终结操作(约简)

。。。