【函数式编程】StreamAPI

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的主要作用

  1. 集合对象提供了一种查询和转化的新方式。
  2. 引入了函数式编程的概念,使得操作更加简洁灵活。
  3. 支持并行(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博客

总结

  1. stream流对于继承Collection集合的类的操作很是方便
  2. 对于大数组的操作效率更高
  3. stream与lambda表达式天生适配
相关推荐
姜学迁1 小时前
Rust-枚举
开发语言·后端·rust
爱学习的小健2 小时前
MQTT--Java整合EMQX
后端
北极小狐2 小时前
Java vs JavaScript:类型系统的艺术 - 从 Object 到 any,从静态到动态
后端
【D'accumulation】2 小时前
令牌主动失效机制范例(利用redis)注释分析
java·spring boot·redis·后端
2401_854391082 小时前
高效开发:SpringBoot网上租赁系统实现细节
java·spring boot·后端
Cikiss2 小时前
微服务实战——SpringCache 整合 Redis
java·redis·后端·微服务
Cikiss2 小时前
微服务实战——平台属性
java·数据库·后端·微服务
OEC小胖胖3 小时前
Spring Boot + MyBatis 项目中常用注解详解(万字长篇解读)
java·spring boot·后端·spring·mybatis·web
2401_857617623 小时前
SpringBoot校园资料平台:开发与部署指南
java·spring boot·后端
计算机学姐3 小时前
基于SpringBoot+Vue的在线投票系统
java·vue.js·spring boot·后端·学习·intellij-idea·mybatis