定义
什么是Stream流,Java doc中是这样写的
A sequence of elements supporting sequential and parallel aggregate operations
翻译一下就是一个支持顺序和并行聚合操作的元素序列。
可以把它理解成一个迭代器,但是只能遍历一次,就像是流水一样,要处理的元素在流中传输,并且可以在流中设置多个处理节点,元素在经过每个节点后会被节点的逻辑所处理。比如可以进行过滤、排序、转换等操作。
Stream流的使用可以分为三个步骤:
- 数据源,创建流
- 中间操作,可以有多个,生成一个新的流
- 终端操作,只能有一个,放在最后,代表流中止。
Stream流有几个特点:
1、Stream流一般不会改变数据源,只会生成一个新的数据流。
2、Stream流不会存储数据,只会根据设置的操作节点处理数据。
3、Stream流是延迟执行的,只有在调用终端操作后才会进行流转。
看一下Stream的结构
使用
数据源生成流
- 如果是集合的话,可以直接使用
stream()
创建流。 - 如果是数组的话,可以使用
Arrays.stream()
或Stream.of()
来创建流。
// 集合生成流
List<String> strList = new ArrayList<>();
Stream<String> stream = strList.stream();
//数据生成流
String[] strs = new String[]{
"1","2","3"};
Stream<String> stream1 = Arrays.stream(strs);
Stream<String> stream2 = Stream.of(strs);
中间操作
在上边Stream定义中,返回是Stream
类型的大多数都是中间操作,入参大多数都是函数式编程,不熟悉的可以看看这篇Java函数式编程。常用的中间操作有
- 过滤操作
filter()
Arrays.stream(strs).filter(s -> s.equals("1"));
- 排序操作
sorted()
Arrays.stream(strs).sorted();
- 去重操作
distinct()
Arrays.stream(strs).distinct();
- 映射操作,将流中元素转换成新的元素
mapToInt()
转换成Integer类型mapToLong()
转换成Long类型mapToDouble()
转换成Double类型map()
自定义转换类型,这是一个使用频率非常高的方法。
//将字符串转换成Integer
Arrays.stream(strs).mapToInt(s -> Integer.valueOf(s));
//将字符串转换成Long
Arrays.stream(strs).mapToLong(s -> Long.valueOf(s));
//将字符串转换成Doublde
Arrays.stream(strs).mapToDouble(s -> Double.valueOf(s));
//自定义转换的类型
Arrays.stream(strs).map(s -> new BigDecimal(s));
中间操作是可以有多个的,我们可以根据业务功能组合多个中间操作,比如求数组中字符串包含s的字符串长度排序
Arrays.stream(strs).filter(e->e.contains("s")).map(String::length).sorted();
终端操作
终端操作,表示结束流操作,是在流的最后,常用的有
- 统计
count()
long count = Arrays.stream(strs).count();
// count=3
- 获取最小值
min()
// 将字符串转换成Interger类型再比较大小
OptionalInt min = Arrays.stream(strs).mapToInt(Integer::valueOf).min();
System.out.println(min.getAsInt());
// 1
- 获取最大值
max()
OptionalInt max = Arrays.stream(strs)