Stream流03-终结方法

基于前面讲的创建Stream流和Stream的中间方法,今天我们来说Stream流的终结方法,终结方法主要有以下四个:遍历、统计、收集(收集流中的数据,存放到数组中)、收集(收集流中的数据,存放到集合中)


首先就是遍历(forEach)

依次获取流里面的数据

我们看forEach的底层代码,可以发现其实forEach底层就是个函数式接口,所以我们要将其改成lambda表达式

函数式接口的具体内容可以参考函数式接口

代码如下

package com.itheima;

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Consumer;

public class StreamDemo9 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢光坤");

        //遍历 void foreach(Consumer action)

        //consumer的泛型:表示流中数据的类型
        //accept方法的形参s:表示流里面的每一个数据
        //方法体:对每一个数据的处理操作(打印)
        list.stream().forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
    }
}

我们将其改成lambda表达式

图中我们可以发现forEach的返回值为void,这表明forEach方法结束后,不能在调用流里面的其他方法(就是后面不能再加“点”什么了),即终结方法

list.stream().forEach(s -> System.out.println(s));

统计(count)

我们可以发现,count类型的返回值是一个long类型的整数,所以同上,他也不能在调用流里面的其他方法了,即中介方法

long count = list.stream().count();
        System.out.println(count);

收集(toArray())

收集流中数据,放到数组中

我们可以发现,toArray有两种,观察其返回类型,我们需要具体的类型,所以调用下面的那个方法

        //toArray()        收集流中数据,放到数组中
        //IntFunction的泛型:具体类型的数组
        //apply的形参:流中数据的个数,要跟数组恶长度保持一致
        //apply的返回值:具体类型的数组
        //方法体:创建数组
        //toArray方法的参数的作用:负责创建一个指定类型的数组
        //toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组当中
        //toArray方法的返回值:是一个装着流里面所有数据的数组
        String[] arr = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(arr));

将其改成lambda表达式

String[] arr2 = list.stream().toArray((value) -> new String[value]);
        System.out.println(Arrays.toString(arr2));

收集集合(collect)

收集流中的数据,放到集合中(List,Set,Map)

首先,我们收集到list集合中

package com.itheima;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class StreamDemo10 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌-男-15", "周芷若-女-14", "赵敏-女-13", "张强-男-20", "张三丰-男-100", "张翠山-男-40", "张良-男-35", "王二麻子-男-37", "谢光坤-男-41");

        //收集list集合当中
        //需求:把所有的男性收集起来
        List<String> newList = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toList());

        System.out.println(newList);
    }
}

第二种,收集到set集合中

//收集set集合当中
        //需求:把所有的男性收集起来
        //.collect(Collectors.toSet());会在底层创建一个hashset的集合,并把流里面的数据放到set集合当中
        Set<String> newList2 = list.stream().filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toSet());
        System.out.println(newList2);

区别:收集到list不会去重

hashset会把重复值去掉

第三种,收集到map集合中

调用map方法,需要设置其键和值

我们观察底层代码,找到键和值的约定规则

我们按照上述规则对代码进行编写(注释中有对应的解释)

 //收集set集合当中
        //需求:把所有的男性收集起来
        //.collect(Collectors.toSet());会在底层创建一个hashset的集合,并把流里面的数据放到set集合当中
        Set<String> newList2 = list.stream().filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toSet());
        System.out.println(newList2);

        //收集map集合当中
        //谁作为键,谁作为值
        // 需求:把所有的男性收集起来 键:姓名 值:年龄 //
        // new Function中第一个泛型表示流里面的数据类型,第二个泛型表示MAP集合当中键(姓名)的类型
        Map<String, Integer> map = list.stream().filter(s -> "男".equals(s.split("-")[1]))
                /*
                 *   toMap : 参数1表示键的生成规则
                 *           参数2表示值的生成规则
                 *   参数一:
                 *          Function:泛型1:表示流中每一个数据的类型
                 *                    泛型2:表示Map集合中键的数据类型
                 *
                 *           方法apply形参:依次表示流里面的每一个数据
                 *                   方法体:生成键的代码
                 *                   返回值:已经生成的键(string、integer)
                 * */

                .collect(Collectors.toMap(new Function<String, String>() {
                                              @Override
                                              public String apply(String s) {
                                                  //张无忌-男-15
                                                  return s.split("-")[0];
                                              }
                                          },
                        new Function<String, Integer>() {
                            @Override
                            public Integer apply(String s) {
                                return Integer.parseInt(s.split("-")[2]);
                            }
                        }));
        System.out.println(map);

需要注意的是:如果我们要收集到Map集合当中,map中的键不能重复,否则会报错!

至于为什么会这样,我们可以简单查看一下toMap的源码

底层封装了putIfAbsent这样一个方法,具体解释是:根据键先找值,如果值为null,表示当前键为空的,是不存在的,这是就可以把数据添加到map集合中,但是如果重复,进行第二次添加的时候v就不是null了

如果不为null,就会产生一个异常

上面是我们用匿名内部类写的toMap方法

最后我们要将其写成lambda表达式

Map<String, Integer> map2 = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toMap(
                        s -> s.split("-")[0],
                        s -> Integer.parseInt(s.split("-")[2])
                ));
        System.out.println(map2);

以上就是我们stream流的所有终结方法了,结合前面我们总结一下stream流

1.Stream流的作用

结合Lambda表达式,简化集合、数组的操作

2.Stream流的使用步骤

  •  获取Stream流对象
  •  使用中间方法处理数据
  • 使用终结方法处理数据

3.如何获取Stream流对象

  • 单列集合:Collection中的默认方法stream
  • 双列集合:不能直接获取
  • 数组:Arrays工具类型中的静态方法stream
  • 一堆零散的数据:Stream接口中的静态方法of

4.常见方法

中间方法:filter,limit,skip,distinct,concat,map

终结方法:forEach,count,collect(set,list,map)

  • 17
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余阳867

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值