Java核心技术知识点笔记—Java SE 8的流库

前言:流提供了一种在比集合更高的概念级别上指定计算的数据视图。通过流,可以将操作的调度留给具体实现去解决。

1、用流操作代替迭代:

通常我们使用迭代遍历集合的元素并执行某项操作。例如,计算一个字符串集合中长单词的个数,使用迭代的方式:

List list = Arrays.asList("ArrayList", "Arrays", "String", "class", "main");
int count = 0;
for (String s : list) {
    if (s.length() > 5) {
        count++;
    }
}
System.out.print(count);

使用流的方式:

List list = Arrays.asList("ArrayList", "Arrays", "String", "class", "main");
long count = list.stream().filter(s -> s.length() > 5).count();
System.out.print(count);

1.1、流遵循了“做什么而非怎么做”的原则。只需描述需要“做什么”,而不用确切地指定“怎么做”。

1.2、流与集合的差异:

(1)流不存储其元素。元素可能存储在底层的集合中,或按需生成。

(2)流的操作不会修改其数据源。例如filter方法不会从流中移除元素,而是会生成一个新的流,其中不包含与条件不符合元素。

(3)流的操作是尽可能惰性执行的。这意味着直至需要其结果时,操作才会执行。例如上例,只想在前n个元素中查找,那么filter方法将在查到到第n个元素后停止操作。因此,使用甚至可以操作无限流。

1.3、操作流的典型流程:

(1)创建一个流;

(2)指定将初始流转换为其他流的中间操作,可能包含多个步骤;

(3)应用终止操作,产生结果。这个操作会强制执行之前的惰性操作。至此,这个流无法再使用。

2、流的创建:

2.1、上述例子已经看到了Collection接口的stream方法将集合转换为一个流的操作。下面还有几种方式:

(1)Stream.of(T... values)方法:具有可变长参数,可以创建具有任意数量引元的流。

Stream stream = Stream.of("Stream", "of", "流", "123");

(2)Stream.generate(Supplier s)方法:创建无限流的静态方法。

Stream generate = Stream.generate(() -> "generate");//创建一个常量值的流
Stream generate1 = Stream.generate(Math::random);//产生无限序列

(3)Arrays.stream()方法:有多个不同参数类型和个数的方法,可以根据需要选择。

Stream stream = Arrays.stream(new String[]{"Arrays", "stream" });

(4)Stream.empty()方法:创建一个不包含任何元素的流。

Stream empty = Stream.empty();

2.2、filter、map和flatMap方法:

流的转换会产生一个新的流,它的元素派生自另一个流中的元素。

(1)filter通过筛选出与条件匹配的元素转换为一个新的流;

(2)map方法接收一个作用于流中元素的函数用来转换流中的值,并生成一个新的流;

(3)flatMap方法与map方法一样用来转换流中的值,同时将生成的新流中的所有元素摊开连接到一起(默认通过“,”分隔)。

2.3、抽取子流和连接流:

(1)Stream.limit(n)方法:产生一个新流,在n个元素之后结束。对于裁剪无限流的尺寸很有用;

(2)Stream.skip(n)方法:丢弃前n个元素,产生一个不包括被丢弃的前n个元素的新流。

(3)Stream.contact(Stream a,Stream b)方法:连接流a和流b,产生一个新的流,其中的元素是包括流a的元素后面加上流b的元素。

2.4、其他的流转换:

(1)Stream.distinct()方法:产生一个流,包含当前流中所有不同的元素;

(2)Stream.sorted(Comparator comparator)方法:产生一个流,其中的元素是当前流按照提供的排序方式排序后的顺序。

(3)Stream.peed(Consumer action)方法:产生一个流,与当前流中的元素相同,在获取每个元素时,会将其传递给action。

你可能感兴趣的:(Java,java,流,Stream)