Stream流的基本使用

开篇

最近开始写一些项目才发现Java8的新特性有一些特别重要的结果自己还没有真正学习过,比如现在在项目中经常用到的Stream流,用于简化代码可以说事半功倍,今天抽了段时间专门来消化这些知识,并通过一个应用来巩固复习一下。

Stream流的使用步骤

  • 获取Stream流对象
  • 使用中间方法处理数据
  • 使用终结方法处理数据
    下面我们一步步来看:

一、获取Stream流对象

  1. 单列集合 default Stream stream() Collections中的默认方法
//获取Stream流,也就是把list中的数据放到stream流中
        Stream<String> stream = list.stream();
  1. 双列集合无法直接使用Stream流,需要先通过keySet()或entrySet()转为单列集合
//法1
       hashMap.entrySet().stream().forEach(s -> System.out.println(s));    
//法2
       hashMap.keySet().stream().forEach(s -> System.out.println(s));
  1. 数组 public static Stream stream(T[] array) Arrays工具类中的静态方法
        String[] a = {"sda","sda","a"};
        Arrays.stream(a).forEach(s-> System.out.println(s));
  1. 一堆零散数据 public static Stream of(T… values) Stream接口中的静态方法
      Stream.of(1,2,3,4,"5").forEach(s-> System.out.println(s));

二、中间方法处理数据

首先我们需要知道一些常用的中间方法,如下:

  /*
        常见中间方法:
        filter 数据过滤
        limit 获取前面几个元素
        skip 跳过前几个元素
        distinct 元素去重(依赖hashcode和equals方法),所以对象记得重写这两个方法
        concat 合并a和b的两个流和为一个
        map 转换流中的数据类型

        注意:
        注意1:中间方法,返回新的Stream流,原来的Stream只能使用1次,所以建议使用链式编程
        注意2:终结方法,返回新的数据,对原来的数据不造成影响
         */

通过代码举例使用:

ArrayList<String> list = new ArrayList<>();
        list.add("cc");
        list.add("cas");
        list.add("caw");
        list.add("44");
        list.add("66");
        list.add("dds");
        //filter
        list.stream().filter(s -> s.startsWith("c")).forEach(s -> System.out.print(s+" "));
        System.out.println();
        System.out.println("=============");
        //skip
        list.stream().skip(2).forEach(s-> System.out.print(s+" "));
        System.out.println();
        System.out.println("=============");

        //取过滤后的跳过2个元素的后面的元素
        list.stream().filter(s -> s.startsWith("c")).skip(2).forEach(s -> System.out.println(s));//caw
        list.add("cc");
        System.out.println();
        System.out.println("=============");

        //distinct
        list.stream().distinct().forEach(s-> System.out.print(s+" "));//ccc as caw 44 66 dds
        System.out.println();
        System.out.println("=============");

        //limit
        list.stream().filter(s -> s.startsWith("c")).limit(2).forEach(s -> System.out.print(s + " "));
        System.out.println();
        System.out.println("=============");

        //concat
        ArrayList<String> strings = new ArrayList<>();
        strings.add("yjh");
        strings.add("wu");
        Stream.concat(list.stream(),strings.stream()).forEach(s -> System.out.print(s+" "));//cc cas caw 44 66 dds cc yjh wu
        System.out.println(" ============= ");
        //map
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("dasd","22");
        hashMap.put("das3d","3");
        hashMap.put("d2asd","33");
        hashMap.put("1dasd","2222");
        //要求将hsahMap中的value值转换成int类型
        //s 就为 dasd=22  ...
        hashMap.entrySet().stream().map(s->Integer.parseInt(s.getValue())).forEach(s-> System.out.print(s+" "));//22 3 33 2222


    }

三、终结方法处理数据

终结方法如下:

在这里插入代码片 /**
         * 终结方法:
         * foreach  遍历
         * count    统计
         * toArray 转数组
         * collect(Collertor collector)   收集流中的数据到(List Set Map)
         */

对于前三种简单的,我们同样使用代码举例使用:

 ArrayList<String> list = new ArrayList<>();
        list.add("cc");
        list.add("cas");
        list.add("caw");
        list.add("44");
        list.add("66");
        list.add("dds");
        list.stream().forEach(s -> System.out.println(s));
        long count = list.stream().count();
        System.out.println(count);
        //Arrays
        //toArray方法参数作用,负责创建一个指定类型的底层
        //toArray方法底层,会依次得到流里面的每一个数据,并把数据放到数组中
        //toArray的返回值:是一个装着流里面的所有数据的数组
        String[] array = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.print(Arrays.toString(array)+" ");//[cc, cas, caw, 44, 66, dds]
        String[] strings = list.stream().toArray(value -> new String[value]);
        System.out.print(Arrays.toString(strings)+" ");//[cc, cas, caw, 44, 66, dds]

    }

第四种,收集流中的数据到(List Set Map等等)
较于前三种比较复杂一些,主要体现在转map的过程中,如下:

public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("cc-1");
        list.add("cas-1");
        list.add("caw-2");
        list.add("44-3");
        list.add("66-1");
        list.add("dds-2");
        //收集-后为1的数据
        // 到List集合中
        List<String> collect = list.stream().filter(s -> "1".equals(s.split("-")[1]))
                .collect(Collectors.toList());
        //到set集合中
        Set<String> collect1 = list.stream().filter(s -> "1".equals(s.split("-")[1]))
                .collect(Collectors.toSet());
        //收集到List和Set的区别就是集合的区别,一个可以重复一个不可以重复嘛
        //到Map集合中,注意:收集到map集合中不能存在重复数据,否则会报错
        /**
         *  toMap:参数一表示键的生成规则
         *        参数二表示值的生成规则
         *  参数一:
         *        Function泛型一:表示流中每个数据的类型
         *                泛型二:表示Map集合中每个键的类型
         *  参数二:
         *        Function泛型一:表示流中每个数据的类型
         *                泛型二:表示Map集合中每个值的类型
         *        方法apply形参:依次表示流里面的每一个数据
         *                 方法体:生成值的代码
         *                 返回值:已经生成的值
         */
        //匿名内部类写法
        Map<String, String> map = list.stream().filter(s -> "1".equals(s.split("-")[1]))
                .collect(Collectors.toMap(new Function<String, String>() {
                                              @Override
                                              public String apply(String s) {
                                                  return s.split("-")[0];
                                              }
                                          },
                        new Function<String, String>() {
                            @Override
                            public String apply(String s) {
                                return s.split("-")[1];
                            }
                        }));
        System.out.println(map);//{66=1, cc=1, cas=1}
        //lambda写法
        Map<String, String> map1 = list.stream().filter(s -> "1".equals(s.split("-")[1]))
                .collect(Collectors.toMap(
                        s -> s.split("-")[0],
                        s -> s.split("-")[1]
                ));
        System.out.println(map1);//{66=1, cc=1, cas=1}

四、综合应用

在这里插入图片描述

ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("啊啊,23");
        arrayList.add("呜呜呜呜,24");
        arrayList.add("阿萨德,25");
        arrayList.add("嗷嗷,25");
        arrayList.add("急急急,25");
        arrayList.add("阿闪大,25");
        //1.男的只要3个字的前两个人
        List<String> boyList = arrayList.stream()
                .filter(x -> x.split(",")[0].length() == 3)
                .limit(2)
                .collect(Collectors.toList());
        System.out.println(boyList);//[阿萨德,25, 急急急,25]

        ArrayList<String> arrayList1 = new ArrayList<>();
        arrayList1.add("杨孩子1,23");
        arrayList1.add("杨孩子2,24");
        arrayList1.add("女孩子,25");
        arrayList1.add("女孩子2,25");
        arrayList1.add("女孩子3,25");
        arrayList1.add("女孩1子,25");
        //2.女孩只要只要姓杨的且不要第一个
        List<String> girlList = arrayList1.stream()
                .filter(x -> x.startsWith("杨"))
                .skip(1)
                .collect(Collectors.toList());
        System.out.println(girlList);//[杨孩子2,24]

        //3.把过滤后的男的和女的拼成一个list
        List<String> boyAndGirlList = Stream.concat(boyList.stream(), girlList.stream())
                .collect(Collectors.toList());
        System.out.println(boyAndGirlList);//[阿萨德,25, 急急急,25, 杨孩子2,24]

        //4.上一步的信息封装成Actor对象并存入一个list中
        ArrayList<Actor> actors = new ArrayList<>();
        for (String ac : boyAndGirlList) {
            String[] split = ac.split(",");
            Actor actor = new Actor();
            actor.setName(split[0]);
            actor.setAge(Integer.parseInt(split[1]));
            actors.add(actor);
        }
        System.out.println(actors);
        //[Actor{name='阿萨德', age=25}, Actor{name='急急急', age=25}, Actor{name='杨孩子2', age=24}]

        //3,4可通过map转换来合并
        List<Actor> actorList = Stream.concat(boyList.stream(), girlList.stream())
                .collect(Collectors.toList())
                .stream().map(x -> new Actor(x.split(",")[0], Integer.parseInt(x.split(",")[1])))
                .collect(Collectors.toList());
        System.out.println(actorList);
        //[Actor{name='阿萨德', age=25}, Actor{name='急急急', age=25}, Actor{name='杨孩子2', age=24}]

5、总结

Stream流结合了Lambda表达式,简化了集合、数组的操作,让很多对集合操作的长段代码大幅度缩减。虽然这不可避免地让代码的可读性变差了一些,但实用性却是毋庸置疑的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值