https://www.cnblogs.com/owenma/p/12207330.html

一、概述

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。
使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。
也可以使用 Stream API 来并行执行操作。
简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

特点:
1. 不是数据结构,不会保存数据。
2. 不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。(保留意见:毕竟peek方法可以修改流中元素)
3. 惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。

二、分类

分类

无状态:指元素的处理不受之前元素的影响;
有状态:指该操作只有拿到所有元素之后才能继续下去。
非短路操作:指必须处理所有元素才能得到最终结果;
短路操作:指遇到某些符合条件的元素就可以得到最终结果,如 A || B,只要A为true,则无需判断B的结果。

三、具体用法

1. 流的常用创建方法

1.1 使用 Collection 下的 stream() 和 parallelStream() 方法

1
2
3
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); // 获取一个顺序流
Stream<String> parallel = list.parallelStream(); // 获取一个并行流

1.2 使用 Arrays 中的 steam() 方法,将数组转为流

1
2
Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);

1.3 使用 Stream 中的静态方法:of()、iterate()、generate()

1
2
3
4
5
6
7
8
Stream<Integer> stream1 = Stream.of(1,2,3,4,5,6);
stream1.forEach(System.out::print);
System.out.println(); // 123456
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 2).limit(6);
stream2.forEach(System.out::print); // 0246810
System.out.println();
Stream<Double> stream3 = Stream.generate(Math::random).limit(2);
stream3.forEach(System.out::print); // 0.94377593451693040.8770729330698199

1.4 使用 BufferedReader.lines() 方法,将每行内容转成流

1
2
3
BufferedReader reader = new BufferedReader(new FileReader("D:\\Projects\\java-demo\\.gitignore"));
Stream<String> lineStream = reader.lines();
lineStream.forEach(System.out::println);

1.5 使用 Pattern.splitAsStream() 方法,将字符串分隔成流

1
2
3
Pattern pattern = Pattern.compile(",");
Stream<String> stringStream = pattern.splitAsStream("a,b,c,d");
stringStream.forEach(System.out::print);

2. 流的中间操作