StreamAPI
streamApi是Java8引入的一个接口,它与lamda表达式浑然天成的,可以算是lambda表达式的完美搭档。
Stream对象里有很多方法,传入的参数都是函数式接口,去源码看看
swift
public interface Stream<T> extends BaseStream<T, Stream<T>> {
Stream<T> filter(Predicate<? super T> predicate);
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
可以看到它里面的方法的参数有Predicate
接口, Function
接口等,你进去看看,会发现它们都是函数式接口,而且方法返回的也是Stream对象,所以可以多次操作。
函数式接口又支持Lambda,所以说Stream是Lambda表达式的最佳搭档不过分吧。
Stream API的主要作用
- 为集合对象提供了一种查询和转化的新方式。
- 引入了函数式编程的概念,使得操作更加简洁灵活。
- 支持并行(parallel) 提高运行效率,一般来说,for循环是更快的,但是Stream支持并行,大任务分为小任务去执行;因此,很大的集合对象肯定是Stream处理更快的。
这个API主要在能迭代的对象里使用,比如实现了Collection接口的类。
我觉得他极大的简化了集合代码遍历及其操作。
举个例子: 我现在有一个集合,我要找到姓名为a开头的人,然后在这些以a开头的人中的倒序打印三个名字。
一般写法
csharp
public class Solution {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("abc");
list.add("bcd");
list.add("acd");
list.add("dbc");
list.add("obc");
list.add("abf");
list.add("abz");
ArrayList<String> res1 = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
if(list.get(i).startsWith("a")){
res1.add(list.get(i));
}
}
res1.sort((a, b) -> CharSequence.compare(b, a));
for (int i = 0; i < 3; i++) {
System.out.println(res1.get(i));
}
}
}
Stream流写法
scss
list.stream().filter((o)->o.startsWith("a")).sorted((a,b)-> CharSequence.compare(b,a)).
limit(3).forEach(System.out::println);
Stream运行原理
大家可能很好奇,为啥使用之后就可以很简单的操作集合元素。
我们用它的map方法举例。
当我们对集合元素进行stream()方法时,会获得一个实现了Stream()接口的对象,使用Stream指向该对象,该对象里的map实现形如:
该Stream()会拿到集合的迭代器引用,不断的迭代,然后对里面的对象进行mapper操作,当然,这个mapper操作是我们在函数外面传入的lambda表达式。
该方法会对集合里的每一个元素进行操作,同时返回一个Stream对象,可以进行进一步的处理。
总的来说,就是每次操作都创建一个ArrayList,然后将操作之后的结果放进这个list,然后返回它的stream流。
一些常用的函数使用
count
作用: 用于获取集合的数量
参数: 无
返回值: long
skip
作用: 跳过n个集合元素
参数: long size
返回值: Stream流
map
stream运行原理里面介绍了map:
作用: 对每一个集合函数进行操作
参数:Function函数式接口
返回值: Stream流
使用:
c
list.stream().map((o)-> o + "hhh");
forEach
作用: 遍历每一个集合元素,然后进行一些操作。
参数: Consumer 函数式接口
返回值: void
源码:
使用:
scss
list.stream().forEach(o-> System.out.println(o));
使用这个方法之后就不能再调用方法了,因为返回值为void。
filter
作用: 过滤集合中一些数据
参数: Predicate函数式接口
返回值: Stream流
源码:
使用:
scss
list.stream().filter((o)->o.startsWith("a"));
reduce
作用: 集合中的数据的累积操作
返回值: Stream流
它有多个重载函数,下面有具体的介绍: Stream的reduce的使用_stream.reduce-CSDN博客
总结
- stream流对于继承Collection集合的类的操作很是方便
- 对于大数组的操作效率更高
- stream与lambda表达式天生适配