关于流的基础知识
Java 8 新特性之 Stream API 基础
流的生成
1.从数组
1 2 3 4 5
| String[] arr = { "program", "creek", "program", "creek", "java"}; Stream<String>stream = Stream.of(arr);
Stream<String>stream2 = Stream.of("program", "creek", "program", "creek", "java");
|
2.从集合
1 2 3 4
| List<String>strings = Arrays.asList("abc", "cbc", "bbc", "cbc", "uas","cctv", "cnc");
Stream<String>listStream = strings.stream();
|
3.使用Stream.generate()
static Stream generate(Supplier s) 返回无限顺序无序流,其中每个元素由提供的供应商生成。 这适合于产生恒定流,随机元素流等。通过实现 Supplier 接口,把 Supplier 实例传递给 Stream.generate() 生成的 Stream,默认是串行(相对 parallel 而言)但无序的(相对 ordered 而言)。由于它是无限的,在管道中,必须利用 limit 之类的操作限制 Stream 大小。
1 2 3 4 5 6 7 8 9 10
| Random seed = new Random();
Supplier<Integer>random = seed::nextInt;
Stream.generate(random).limit(10).forEach(System.out::println);
IntStream.generate(() ->(int) (System.nanoTime() % 100)). limit(10).forEach(System.out::println);
|
4.使用Stream.iterate()
static Stream iterate(T seed, UnaryOperator f) 返回通过将函数f迭代应用于初始元素种子产生的无限顺序有序流,产生由种子f(种子),f(f(种子))等组成的流。
Stream中的第一个元素(位置0)将是提供的种子。 对于n> 0,位置n处的元素将是将函数f应用于位置n-1处的元素的结果。
iterate 跟 reduce 操作很像,接受一个种子值,和一个 UnaryOperator(例如 f)。然后种子值成为 Stream 的第一个元素,f(seed) 为第二个,f(f(seed)) 第三个,以此类推。
注意:与 Stream.generate 相仿,在 iterate 时候管道必须有 limit 这样的操作来限制 Stream 大小。
1 2
| Stream.iterate(0, n ->n + 3).limit(10). forEach(x ->System.out.print(x + " "));
|
完整实例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| package com.devnp.java8.stream;
import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.function.Supplier; import java.util.stream.IntStream; import java.util.stream.Stream;
public class CreateStreamDemo {
public static void main(String[] args) { String[] arr = { "program", "creek", "program", "creek", "java"}; Stream<String>stream = Stream.of(arr); Stream<String>stream2 = Stream.of("program", "creek", "program", "creek", "java"); List<String>strings = Arrays.asList("abc", "cbc", "bbc", "cbc", "uas","cctv", "cnc"); Stream<String>listStream = strings.stream(); Random seed = new Random(); Supplier<Integer>random = seed::nextInt; Stream.generate(random).limit(10).forEach(System.out::println); IntStream.generate(() ->(int) (System.nanoTime() % 100)). limit(10).forEach(System.out::println); Stream.iterate(0, n ->n + 3).limit(10). forEach(x ->System.out.print(x + " "));
}
}
|
用 Collectors 来进行 reduction 操作
java.util.stream.Collectors 收集者实施各种有用的还原操作,如将元素累积到收藏中,根据各种标准汇总元素等,主要作用就是辅助进行各类有用的 reduction 操作.
groupingBy/partitioningBy
例如统计字符串出现的次数:
1 2 3
| List<String>strings = Arrays.asList("abc", "cbc", "abc", "cbc", "uas","cctv", "cnc");
Map<String, Long>result = strings.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
|
例如找出“abc”字符串:
1 2
| List<String>strings = Arrays.asList("abc", "cbc", "abc", "cbc", "uas","cctv", "cnc"); Map<Boolean, List<String>>result2 = strings.stream().collect(Collectors.partitioningBy(p ->p.equals("abc")));
|
完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.devnp.java8.stream;
import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors;
public class CollectorsDemo {
public static void main(String[] args) {
List<String>strings = Arrays.asList("abc", "cbc", "abc", "cbc", "uas","cctv", "cnc"); Map<String, Long>result = strings.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); System.out.println(result); System.out.println("---------------"); Map<Boolean, List<String>>result2 = strings.stream().collect(Collectors.partitioningBy(p ->p.equals("abc"))); System.out.println(result2); }
}
|
运行结果:
[code lang=”text”]
{abc=2, cbc=2, uas=1, cnc=1, cctv=1}
{false=[cbc, cbc, uas, cctv, cnc], true=[abc, abc]}
```
总结
- Stream 不是数据结构,没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。
- Stream 也绝不修改自己所封装的底层数据结构的数据。
- Stream 的操作必须以 lambda 表达式为参数
- 不支持索引访问
- 惰性化
- Stream 操作是向后延迟的,一直到它弄清楚了最后需要多少数据才会开始。
- 当一个 Stream 是并行化的,就不需要再写多线程代码,所有对它的操作会自动并行进行的。
- 集合有固定大小,Stream 则不必, 可以是无限的.
Author:
Darren Du
License:
Copyright (c) 2019 MIT LICENSE