【JAVA8新特性】 stream流API

Java8引入的StreamAPI提供了一种高效处理集合数据的方式,包括并行流和串行流。它抽象了对集合的常见操作,如过滤、映射和判断等,类似SQL查询。Stream不是数据结构,而是处理数据的过程,不存储数据也不改变源集合。例如,通过filter和map方法,可以方便地对集合进行过滤和转换操作。
摘要由CSDN通过智能技术生成

JAVA

推出了一些很好用的新特性 这里先讲一下stream 流

什么是 stream 流

这个名字本身就容易让新手混淆,因为编程领域里面有很多东西名字都带有stream,比如BIO 里面有的IO流 inputstream ,outputstream, 比如大数据里面有流式计算,会有什么什么steam之类的。

但是这篇说的跟上面这些没有毛线关系,这里的stream指的是 java 8里面新引入的一套API :流 stream

怎么理解这个东西? 应该说他是一种对java集合(比如数组 比如list 比如map)的操作抽象,在没有stream之前,我们常见的集合操作,比如list, 我们可以遍历这个list , 可以查找这个list中某个元素,可以对list中的元素做处理,比如按条件过滤后 生成新的list等等等。 而stream流的引进就是帮我们抽象了这些常用的操作,所以它是本质上一个处理数据的过程。

这里举一个很形象的例子 就是sql里面的视图, 视图不是具体的数据 它是把你对sql的一些复杂操作 抽象起来,它是一个数据计算的过程。 所以我们在理解jdk8的stream流的时候 很重要的一点就是 它不是一个数据结构 不是一个集合,它是一种处理数据计算数据的过程抽象,它本身不存储数据 也不会改变源对象集合。

Stream APl对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用Stream API来并行执行操作。简而言之,StreamAPI提供了一种高效且易于使用的处理数据的方式。

再举一个例子 比如你有一个面包, 然后你想切它,那么你自己指定了一个过程规则:横竖两刀 切 切成4块, 然后每当你拿到一个面包 你就直接用这个规则去切它,这个面包就是数据集合 而你指定的这个切面包的规则和切的过程就是stream流。 它只是一个处理过程 而不是面包本身。


stream流的两大类

java 8 提供了 并行流(并发场景中使用) 和 串行流 (常用的同步场景),大多数情况下 我们使用的都是 串行流,用来在代码中对 各种集合进行高效 易用的操作。

stream流对集合的操作

这里就是核心了 上面讲了 stream引入java8 它的最大作用就是对集合进行操作。 那么它能进行哪些操作呢?
我们先来一个大概的分类:

在这里插入图片描述

主要关注最常用的前两种,新手先不用管第三者。

在下面的表格在有各种 ***() 方法 全部是steam可以对集合进行各种操作,第一眼看名字就知道常用的 什么查找 排序 筛选 映射等 啥都有,之前这些操作都需要你手写,现在好了 可以直接白嫖!

这些操作被分为两大类 中间操作终止操作
这个很好理解 中间操作就是 stream对集合进行操作 操作的结果暂时还是stream意思就是说它还在对集合的操作过程当中, 而终止操作就是stream对集合操作结束 得到结果是一个新的集合 说明stream执行结束了。


实践

理论都懂了 现在就这里面的一些经常用的操作 来实践一下 体会一下stream操作的感觉。
既然是对集合操作 那我们先随便搞一个测试用的集合
list<Student
创建一个student类的集合属性依次是 id 姓名 排名 性别 true/false =男/女

        List<Student>studentList = new LinkedList<>();
        studentList.add(new Student(1L,"maru",1,true));
        studentList.add(new Student(2L,"serral",13,true));
        studentList.add(new Student(3L,"dark",25,false));
        studentList.add(new Student(4L,"zest",40,true));
        studentList.add(new Student(5L,"time",42,false));
        studentList.add(new Student(6L,"clem",50,true));
        studentList.add(new Student(7L,"solar",65,true));

stream 操作函数很多 这里主要说一下 最常用的几个操作 ,理解之后其他的一通百通 用的时候直接搜即可,我们平时在业务代码里面最常用到的有:

filter

filter 是过滤用的 可以把过滤条件作为参数 :

比如我们按排名<30 过滤上面的student:

studentList.stream().filter(student -> student.getRanking() < 30)

这里的filter(student -> student.getRanking() < 30) 你可以理解为数据里面的函数,函数入参是student对象,——> 后对每一个对象做条件过滤操作。 就可以筛选出 student.getRanking() < 30 的对象。

但是前面说了filter是中间操作 所以上面代码得到的是一个流 而不是list对象。 所以后面加上收集器:

List<Student> studentsOfFilter = studentList.stream().filter(student -> student.getRanking() < 30).collect(Collectors.toList());

就这样 执行一下 一个过滤流操作就完成了:

按ranking过滤_输出结果:
maru
serral
dark

Process finished with exit code 0

这里就体现了stream的便捷性,如果按照传统的方法 我们还得新建一个list for循环判断过滤旧list 然后符合条件的放到新的list里面。

注意 filter的操作对象结构是 List 操作完之后得到的结构还是List,后面的map就不是这样了。

map

map应该是平时用的最多的,map的理解是 映射到新集合。 注意第一是映射 ,第二是新集合,map的用途很多都是我们业务场景中 你有一个list<A 需要把A类里面的一些属性取出来处理一下 set到 B类 然后 形成一个list<B . map支持

  • 基础类型 转基础类型 (比如list 转 list)
  • 基础类型 互相转换 对象类型
  • 对象类型 转 对象类型

非常灵活。

比如上面的 list<student 我们现在只想要 里面的name那一列 单独成一个list<String:

 List<String> nameList = studentList.stream().map(s -> s.getName()).collect(Collectors.toList());

一行代码就搞定了。

再比如 我们现在是 student 我们再创建一个 scplay类 把list<student 映射过去:

public class ScPlayer {

    //姓名
    private String name;

    //年级排名
    private int grade;

    //性别
    private String race;

}
        List<ScPlayer> scPlayers = studentList.stream().map(s -> {
            ScPlayer scPlayer = new ScPlayer();
            scPlayer.setName(s.getName());
            if (s.getRanking() < 10) {
                scPlayer.setGrade(1);
            } else if (s.getRanking() >= 11 && s.getRanking() < 20) {
                scPlayer.setGrade(2);
            } else {
                scPlayer.setGrade(3);
            }
            scPlayer.setRace("Terran");
            return scPlayer;
        }).collect(Collectors.toList());

        scPlayers.forEach(System.out::println);

这里方法里面变成了{ } ,因为里面创建新对象 记得最后要return返回

anymatch/allmatch

再说两个判断用的,会用过滤条件对 集合内的所有元素进行判断,any就是只要有一个符合就true,all就是全部符合才行:

         //anymatch
        boolean anyMatch40 = studentList.stream().anyMatch(s -> s.getRanking() == 40);
        System.out.println("anyMatch40: "+anyMatch40);

        //allmatch
        boolean allMatch40 = studentList.stream().allMatch(s -> s.getRanking() == 40);
        System.out.println("allMatch40: "+allMatch40);
anyMatch40: true
allMatch40: false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值