【函数式编程】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表达式天生适配
相关推荐
专注VB编程开发20年8 分钟前
asp.net mvc如何简化控制器逻辑
后端·asp.net·mvc
用户67570498850238 分钟前
告别数据库瓶颈!用这个技巧让你的程序跑得飞快!
后端
千|寻1 小时前
【画江湖】langchain4j - Java1.8下spring boot集成ollama调用本地大模型之问道系列(第一问)
java·spring boot·后端·langchain
程序员岳焱1 小时前
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
后端·sql·mysql
龚思凯1 小时前
Node.js 模块导入语法变革全解析
后端·node.js
天行健的回响1 小时前
枚举在实际开发中的使用小Tips
后端
wuhunyu1 小时前
基于 langchain4j 的简易 RAG
后端
techzhi1 小时前
SeaweedFS S3 Spring Boot Starter
java·spring boot·后端
写bug写bug3 小时前
手把手教你使用JConsole
java·后端·程序员