Java中的Stream流

Stream流的思想

流水线思想-->

例:

先进入xx条件过滤,再进入xx条件过滤,......,输出


作用

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


使用步骤


演示

单列集合->

public static void main(String[] args) {
        //单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "a", "b", "c", "d", "e");
        //获取到一条流水线,并把集合中的数据放到流水线上
        Stream<String> stream1 = list.stream();
        //使用终结方法打印流水线上的所有数据
        /*stream1.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                //s:依次表示流水线上的每一个数据
                System.out.println(s);
            }
        });*/
        //一般用Lambda表达式+链式编程简化
        list.stream().forEach(s -> System.out.print(s));//结果abcde
    }

双列集合->

public static void main(String[] args) {
        //创建双列集合
        HashMap<String,Integer> hm = new HashMap<>();
        //添加数据
        hm.put("aaa",111);
        hm.put("bbb",222);
        hm.put("ccc",333);
        //第一种:获取stream流
        hm.keySet().stream().forEach(s -> System.out.print(s));//结果aaacccbbb

        //第二种:获取stream流
        hm.entrySet().stream().forEach(s -> System.out.println(s));//结果aaa=111 ccc=333 bbb=222
    }

数组演示->

public static void main(String[] args) {
        //创建数组
        int[] arr = {1,2,3,4,5,6,7,8,9,10};
        //获取stream流
        Arrays.stream(arr).forEach(s -> System.out.print(s));//结果:12345678910
    }

一堆零散的数据->

public static void main(String[] args) {
        Stream.of(1,2,3,4,5).forEach(s -> System.out.print(s));//结果:12345
    }
注意

Stream流的中间方法

方法演示

filter方法->

ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");

        //filter  过滤
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                //返回值为true:表示当前数据留下
                //返回值为false:表示当前数据舍弃不要
                return s.startsWith("张");
            }
        }).forEach(s -> System.out.print(s + " "));//结果:张无忌 张强 张三丰 张翠山 张良 

代码简化Lambda表达式-->

ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");

        //filter  过滤
        list.stream().filter((String s) -> s.startsWith("张")).forEach(s -> System.out.print(s + " "));//结果:张无忌 张强 张三丰 张翠山 张良

复制代码
limit方法->
ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
        
        //limit   获取前几个元素
        list.stream().limit(3).forEach(s -> System.out.print(s + " "));//张无忌 周芷若 赵敏

skip方法->

ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");

        //skip    跳过前几个元素
        list.stream().skip(3).forEach(s -> System.out.print(s + " "));//张强 张三丰 张翠山 张良 王二麻子 谢广坤 

distinct方法->

ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","张无忌","张无忌","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
        Collections.addAll(list,"周芷若","赵敏");

        //distinct  元素去重(依赖hashCode和equals方法)
        list.stream().distinct().forEach(s -> System.out.print(s + " "));//张无忌 张强 张三丰 张翠山 张良 王二麻子 谢广坤 周芷若 赵敏 

concat方法->

ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1,"张无忌","张无忌","张无忌","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list2,"周芷若","赵敏");

        //concat    合并a和b两个流为一个流
        Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.print(s + " "));//张无忌 张无忌 张无忌 张强 张三丰 张翠山 张良 王二麻子 谢广坤 周芷若 赵敏 

map方法->

ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-18","张强-11","张三丰-25","张翠山-28","张良-30","王二麻子-38","谢广坤-22");

        //只获取里面的年龄并进行打印 String->int

        //第一个类型:表示流中原本的数据类型
        //第二个类型:表示要转成之后的类型

        //apply的形参s:依次表示流里面的每一个数据
        //返回值:转换之后的数据
        list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s){
                String[] arr = s.split("-");
                String ageString = arr[1];
                int age = Integer.parseInt(ageString);
                return age;
            }
        }).forEach(s -> System.out.print(s + " "));//15 14 18 11 25 28 30 38 22 

Lambda简化-->

ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-18","张强-11","张三丰-25","张翠山-28","张良-30","王二麻子-38","谢广坤-22");

        //只获取里面的年龄并进行打印 String->int

        //第一个类型:表示流中原本的数据类型
        //第二个类型:表示要转成之后的类型

        //apply的形参s:依次表示流里面的每一个数据
        //返回值:转换之后的数据
        list.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s -> System.out.print(s + " "));//15 14 18 11 25 28 30 38 22 

Stream流的终结方法

方法演示

forEach方法->

        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);
            }
        });

简化代码-->

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");
        
        list.stream().forEach((String s) -> System.out.println(s));

count方法->

        //long count()  统计
        long count = list.stream().count();
        System.out.println(count);//9

toArray方法->空参

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠山","张良","王二麻子","谢广坤");

        //toArray() 收集流中的数据,放到数据中
        Object[] arr1 = list.stream().toArray();
        System.out.print(Arrays.toString(arr1));//[张无忌, 周芷若, 赵敏, 张强, 张三丰, 张翠山, 张良, 王二麻子, 谢广坤]

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));//[张无忌, 周芷若, 赵敏, 张强, 张三丰, 张翠山, 张良, 王二麻子, 谢广坤]

简写-->

        String[] arr = list.stream().toArray(value -> new String[value]);
        System.out.println(Arrays.toString(arr));//[张无忌, 周芷若, 赵敏, 张强, 张三丰, 张翠山, 张良, 王二麻子, 谢广坤]

collect方法->

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌-男-15","周芷若-女-14","赵敏-女-18","张强-男-11",
                "张三丰-男-25","张翠山-男-28","张良-男-30","王二麻子-男-38","谢广坤-男-22");

        /*
        收集List集合当中
        需求:
        把所有男性收集起来
         */

        List<String> newList = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());
        System.out.println(newList);//[张无忌-男-15, 张强-男-11, 张三丰-男-25, 张翠山-男-28, 张良-男-30, 王二麻子-男-38, 谢广坤-男-22]

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌-男-15","张无忌-男-15","张无忌-男-15","周芷若-女-14","赵敏-女-18","张强-男-11",
                "张三丰-男-25","张翠山-男-28","张良-男-30","王二麻子-男-38","谢广坤-男-22");

        /*
        收集Set集合当中
        需求:
        把所有男性收集起来
         */

        Set<String> newList2 = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toSet());
        System.out.println(newList2);//[张三丰-男-25, 张良-男-30, 张无忌-男-15, 张强-男-11, 张翠山-男-28, 谢广坤-男-22, 王二麻子-男-38]
 
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌-男-15","周芷若-女-14","赵敏-女-18","张强-男-11",
                "张三丰-男-25","张翠山-男-28","张良-男-30","王二麻子-男-38","谢广坤-男-22");

        /*
        收集Map集合当中
        需求:
        把所有男性收集起来
        键:姓名,值:年龄
         */

        Map<String, Integer> map = list.stream().filter(s -> "男"
                        .equals(s.split("-")[1]))
                /*
                toMap:参数一表示键的生成规则
                       参数二表示值的生成规则
                参数一:
                    Function泛型一:表示流中每一个数据的类型
                            泛型二:表示Map集合中键的数据类型

                    方法apply形参:依次表示流里面的每一个数据
                           方法体:生成键的代码
                           返回值:已经生成的键
                参数二:
                    Function泛型一:表示流中每一个数据的类型
                            泛型二:表示Map集合中值的数据类型

                    方法apply形参:依次表示流里面的每一个数据
                           方法体:生成值的代码
                           返回值:已经生成的值
                 */
                .collect(Collectors.toMap(new Function<String, String>() {
                    @Override
                    public String apply(String s) {
                        return s.split("-")[0];
                    }
                }, new Function<String, Integer>() {
                    @Override
                    public Integer apply(String s) {
                        return Integer.parseInt(s.split("-")[2]);
                    }
                }));

        System.out.println(map);//{张强=11, 张良=30, 张翠山=28, 王二麻子=38, 张三丰=25, 张无忌=15, 谢广坤=22}

简化代码-->

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌-男-15","周芷若-女-14","赵敏-女-18","张强-男-11",
                "张三丰-男-25","张翠山-男-28","张良-男-30","王二麻子-男-38","谢广坤-男-22");

        /*
        收集Map集合当中
        需求:
        把所有男性收集起来
        键:姓名,值:年龄
         */

        Map<String, String> map = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toMap(
                        s -> s.split("-")[0]
                        ,
                        s -> s.split("-")[2]
                ));
        System.out.println(map);//{张强=11, 张良=30, 张翠山=28, 王二麻子=38, 张三丰=25, 张无忌=15, 谢广坤=22}

总结

相关推荐
魔道不误砍柴功2 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2342 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨2 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity4 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天5 小时前
java的threadlocal为何内存泄漏
java
caridle5 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^5 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋35 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx
秋の花5 小时前
【JAVA基础】Java集合基础
java·开发语言·windows