【函数式编程】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表达式天生适配
相关推荐
刘大辉在路上2 小时前
突发!!!GitLab停止为中国大陆、港澳地区提供服务,60天内需迁移账号否则将被删除
git·后端·gitlab·版本管理·源代码管理
追逐时光者4 小时前
免费、简单、直观的数据库设计工具和 SQL 生成器
后端·mysql
初晴~4 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱581364 小时前
InnoDB 的页分裂和页合并
数据库·后端
小_太_阳5 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾5 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala
星就前端叭6 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
小林coding7 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
AI理性派思考者7 小时前
【保姆教程】手把手教你在Linux系统搭建早期alpha项目cysic的验证者&证明者
后端·github·gpu