1、什么是Stream流?
流是Java8引入的全新概念,它用来处理集合中的数据,对集合(Collection)对象功能的增强,专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。
Java中的Stream并不会存储元素,而是按需计算,且只能遍历一次。同时结合 Lambda 表达式,极大的提高编程效率和程序可读性。
Stream流采用内部迭代方式,通过访问者模式(Visitor)实现。
若要对集合进行处理,则需我们手写处理代码,这就叫做外部迭代。比如:使用Iterator或for循环来遍历集合。
若要对流进行处理,我们只需告诉流我们需要什么结果,处理过程由流自行完成,这就称为内部迭代。比如:Collection.forEach(…)方法迭代。
2、Stream流的操作种类
流的操作可以分为两种:中间操作和终端操作。
1. 中间操作
当数据源中的数据上了流水线后,这个过程对数据进行的所有操作都称为中间(intermediate)操作。
中间操作可以连接起来,将一个流转换为另一个流。这样多个操作可以串联成一个管道(Pipelining), 如同流式风格(fluent style)。
中间操作都会返回流对象本身。
2. 终端操作
当所有的中间操作完成后,若要将数据从流水线上拿下来,则需要执行终端(Terminal )操作。
一个流只能有一个终端操作,当这个操作执行后,流的操作就结束了,无法再被操作。
Terminal 操作的执行,才会真正开始流的遍历,并且会生成一个结果。
3、Stream流的操作过程
Stream流操作可以分三个步骤:
1、获取一个数据源:可以是集合,数组,I/O channel, 产生器generator 等。
2、中间操作(intermediate operation):
在管道的节点上进行处理,比如: filter、 distinct、 sorted等,它们可以串连起来形成流水线。
3、最终操作( terminal operation):执行终端操作后本次流结束,并返回一个执行结果。
注意:流进行了终止操作后,不能再次使用,否则会报错。
二、获取Stream流对象在使用流之前,需要先拥有一个数据源,并通过 StreamAPI提供的一些方法获取该数据源的 Stearm接口类型流对象。
注意:
- 除了Stream类型外,还有几个IntStream、LongStream、DoubleStream很常用, 因为boxing 和 unboxing 会很耗时,所以特别为这三种基本数值型提供了对应的 Stream。
- 此外还有一个流类型:并行流parallelStream,parallelStream提供了流的并行处理,它是Stream的另一重要特性,其底层使用Fork/Join框架实现。
串行流:适合存在线程安全问题、阻塞任务、重量级任务,以及需要使用同一事务的逻辑。
Stearm类型有:Stream,还有IntStream、LongStream、DoubleStream也很常用,因 boxing和 unboxing会很耗时,所以,这三种基本数值型提供了对应的 Stream。
并行流:流的并行处理,适合没有线程安全问题、较单纯的数据处理任务。
Stearm类型有:并行流parallelStream。
其中 parallelStream()方法能够充分利用多核 CPU的优势,使用多线程加快对集合数据的处理速度。
下面来认识常用的数据源来获取 Stearm对象。后面进行操作的更多方法等,请查看API。
public class User {
private int id;
private String name;
private String sex;
private int age;
private int height;
...
}
1、集合
集合 数据源比较为常用,通过 stream()方法即可获取 Stearm对象。
List list = new ArrayList();
list.add(new User(1, "赵云", "男", 18, 178));
list.add(new User(2, "后裔", "男", 20, 188));
list.add(new User(1, "妲己", "女", 17, 175));
Stream stream = list.stream();
Stream parallelStream = list.parallelStream();
2、数组
通过 Arrays 类提供的静态 stream()方法获取数组的 Stearm对象。
String[] arr = new String[]{"赵云", "后裔", "妲己"};
Stream stream = Arrays.stream(arr);
3、值
直接将几个值变成 Stearm对象,IntStream、LongStream、DoubleStream。
IntStream intStream = IntStream.of(new int[]{1, 2, 3});
LongStream longStream = LongStream.range(1, 3); // [1,3)
LongStream longStream2 = LongStream.rangeClosed(1, 3); // [1,3]
DoubleStream doubleStream = DoubleStream.of(1.0, 3.0);
4、其他创建方法
-
-
static Stream
generate(Supplier s)
返回一个无穷序列无序流,其中每个元素是由提供
Supplier
生成。static Stream
iterate(T seed, UnaryOperator f)
返回一个无穷序列有序
Stream
由最初的一元seed
函数的f
迭代应用产生的,产生一个由seed
,f(seed)
,f(f(seed))
Stream
,等。
-
Stream中的 generate() 很好理解。
iterate () 方法,参数为一个种子值,和一个一元操作符(例如 f)。然后种子值成为 Stream 的第一个元素,f(seed) 为第二个,f(f(seed)) 第三个,以此类推。
注意:这两种方法创建的流是无限的,在管道中,必须利用 limit 之类的操作限制 Stream 大小。
// 生成 10 个随机整数
Stream stream = Stream.generate(new Random()::nextInt).limit(10);
// 生成10个等差(2)数列
Stream stream1 = Stream.iterate(0, n -> n + 2).limit(10);
三、中间操作
1、filter方法:过滤掉不符合谓词判断的数据
-
-
Stream
filter(Predicate
关注打赏
-
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?