Java_Stream流

作用:

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

使用步骤:

①得到一条Stream流(流水线),并把数据放上去

②使用中间方法(如过滤、转换)对流水线上的数据进行操作

③使用终结方法(如统计、打印)对流水线上的数据进行操作

使用方法:

简单代码演示:

单列集合:

要求:

将集合中以a开头且长度为3的元素提取出来

代码演示:
java 复制代码
public class StreamDemo1 {
    public static void main(String[] args) {
        //将以a开头且长度为3的元素提取出来

        //创建集合
        ArrayList<String> list = new ArrayList<>();
        //添加元素
        list.add("aa");
        list.add("bbb");
        list.add("abc");
        list.add("aaa");
        list.add("cca");
        //使用Stream流筛选
        list.stream().filter(str -> str.startsWith("a"))
                .filter(str -> str.length() == 3)
                .forEach(str -> System.out.println(str));
    }
}

(代码思想可以理解为先进行过滤操作留下以a开头的,再进行过滤操作留下长度为3的,最后输出)

运行结果:

双列集合:

代码演示:
java 复制代码
public class StreamDemo2 {
    public static void main(String[] args) {
        HashMap<String,String> hm = new HashMap<>();
        hm.put("a","1");
        hm.put("b","2");
        hm.put("c","3");
        //双列集合不能直接使用Stream
        //所以使用其他两种方法

        //1.对键使用Stream
        hm.keySet().stream().forEach(str -> System.out.println(str));
        //2.对键值对使用Stream
        hm.entrySet().stream().forEach(str -> System.out.println(str));
    }
}
运行结果:

数组:

代码演示:
java 复制代码
public class StreamDemo3 {
    public static void main(String[] args) {
        int[] arr1 = {1,2,3,4,5};
        Arrays.stream(arr1).forEach(num -> System.out.println(num));
        String[] arr2 = {"a","b","c"};
        Arrays.stream(arr2).forEach(str -> System.out.println(str));
    }
}
运行结果:

零散数据:

代码演示:
java 复制代码
public class StreamDemo4 {
    public static void main(String[] args) {
        Stream.of(1,2,3,4,5).forEach(num -> System.out.println(num));
        Stream.of("a","b","c").forEach(str -> System.out.println(str));
    }
}
运行结果:

Stream流的中间方法

注意:

1.中间方法会返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程

2.修改Stream流中的数据,不会影响到原来集合或数组中的数据

代码演示:

java 复制代码
public class StreamDemo5 {
    public static void main(String[] args) {
        //filter 过滤
        //limit 获取前几个元素
        //skip 跳过前几个元素
        //distinct 元素去重(依赖hashCode和equals方法)
        //concat(Stream a, Stream b) 合并a和b两个流为一个流
        //map 转换流中的数据类型

        //创建集合并添加元素
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"蔡徐坤","陈立农","范丞丞","黄明昊"
                ,"林彦俊","朱正廷","王子异","王琳凯","尤长靖");
        //我是ikun别骂我(摘自流行歌曲《我的少年》)

        //分为三部分演示

        //1.
        //filter 过滤
        //limit 获取前几个元素
        //skip 跳过前几个元素
        System.out.println("----------1----------");

        //filter 过滤
        //返回王姓人物
        //1.使用Lambda表达式
        list.stream()
                .filter(s -> s.startsWith("王"))
                .forEach(s -> System.out.println(s));
        //2.未使用Lambda表达式时
        /*list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("王");
            }
        }).forEach(s -> System.out.println(s));*/

        //limit 获取前几个元素
        System.out.println();
        list.stream()
                .limit(3)
                .forEach(s -> System.out.println(s));

        //skip 跳过前几个元素
        System.out.println();
        list.stream()
                .skip(5)
                .forEach(s -> System.out.println(s));

        //练习 获取这三位 "黄明昊","林彦俊","朱正廷"
        System.out.println();
        list.stream()
                .skip(3)
                .limit(3)
                .forEach(s -> System.out.println(s));


        //2.
        //distinct 元素去重(依赖hashCode和equals方法)
        //concat(Stream a, Stream b) 合并a和b两个流为一个流
        System.out.println("----------2----------");
        ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1,"蔡徐坤","蔡徐坤","蔡徐坤","陈立农","陈立农","范丞丞");
        ArrayList<String> list2= new ArrayList<>();
        Collections.addAll(list2,"黄明昊","林彦俊","朱正廷","王子异","王琳凯","尤长靖");
        //distinct 元素去重(依赖hashCode和equals方法)
        list1.stream().distinct().forEach(s -> System.out.println(s));

        //concat(Stream a, Stream b) 合并a和b两个流为一个流
        System.out.println();
        Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.println(s));


        //3.
        //map 转换流中的数据类型
        System.out.println("----------3----------");
        //创建集合并存储元素
        ArrayList<String> list3 = new ArrayList<>();
        Collections.addAll(list3,"蔡徐坤-18","陈立农-19","范丞丞-20","黄明昊-21"
                ,"林彦俊-22","朱正廷-23","王子异-24","王琳凯-25","尤长靖-26");

        //1.不使用Lambda
        list3.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                String[] arr = s.split("-");
                String ageString = arr[1];
                int num = Integer.parseInt(ageString);
                return num;
            }
        }).forEach(s -> System.out.print(s + " "));

        //2.使用Lambda
        System.out.println();
        list3.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s -> System.out.print(s + " "));

    }

运行结果:

Stream流的终结方法:

代码演示:

这里先演示前三个方法,collect后面独立演示

java 复制代码
public class StreamDemo6 {
    public static void main(String[] args) {
        //创建集合并添加元素
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"蔡徐坤","陈立农","范丞丞","黄明昊"
                ,"林彦俊","朱正廷","王子异","王琳凯","尤长靖");

        // void forEach(Consumer action)    遍历
        System.out.println("----------------------------");
        //使用Lambda
        list.stream().forEach(s -> System.out.print(s + " "));
        //不使用Lambda
        System.out.println();
        list.stream().forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.print(s + " ");
            }
        });

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

        // toArray()        收集流中的数据,放到数组中
        System.out.println("----------------------------");
        //空参构造
        Object[] array1 = list.stream().toArray();
        System.out.println(Arrays.toString(array1));
        //带参构造
        String[] array2 = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(array2));
        //Lambda表达式
        String[] array3 = list.stream().toArray(value -> new String[value]);
        System.out.println(Arrays.toString(array3));

    }
}

运行结果:

collect方法代码演示

java 复制代码
public class StreamDemo7 {
    public static void main(String[] args) {
        //collect(Collector collector)  收集流中的数据,放到集合中

        //创建集合并添加元素
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"小白-男-20","小白-男-20","小黑-男-21","小红-女-22","小蓝-男-23","小紫-女-24");

        //1.放到List集合
        //要求:筛选男性
        List<String> newList = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toList());
        System.out.println(newList);

        //2.放到Set集合
        //要求:筛选男性
        //放到Set集合中会去重
        Set<String> newSet = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toSet());
        System.out.println(newSet);

        //3.放到Map集合
        //要求:筛选男性 并且将姓名作为键,将年龄作为值
        //注意:放入Map集合中要求集合中不得有相同的键
        //调用toMap()后括号中的两个参数为键的规则和值的规则

        //创建新集合
        ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1,"小白-男-20","小黑-男-21","小红-女-22","小蓝-男-23","小紫-女-24");

        //未使用Lambda表达式
        Map<String, Integer> newMap = list1.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .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(newMap);

        //使用Lambda表达式
        Map<String, Integer> newMap2 = list1.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[2])));
        System.out.println(newMap2);

    }
}

运行结果:

三个小练习

练习一:

定义一个集合,并添加一些整数

1,2,3,4,5,6,7,8,9,10

过滤奇数,只留下偶数

并将结果保存

代码:
java 复制代码
public class StreamTest1 {
    public static void main(String[] args) {
        /*
        定义一个集合,并添加一些整数
        1,2,3,4,5,6,7,8,9,10
        过滤奇数,只留下偶数
        并将结果保存
        */

        //创建集合并添加元素
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);
        //过滤奇数,并存储到新集合
        List<Integer> newList = list.stream().filter(num -> num % 2 == 0).collect(Collectors.toList());
        System.out.println(newList);
    }
}
运行结果:
练习二:

创建一个ArrayList集合,并添加以下字符串

字符串中前面是姓名,后面是年龄

"zhangsan,23" "lisi,24" "wangwu,25"

保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值

代码:
java 复制代码
public class StreamTest2 {
    public static void main(String[] args) {
        /*
        创建一个ArrayList集合,并添加以下字符串
        字符串中前面是姓名,后面是年龄
        "zhangsan,23"
        "lisi,24"
        "wangwu,25"
        保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
        */

        //创建集合并添加元素
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"zhangsan,23","lisi,24","wangwu,25");

        //保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
        Map<String, Integer> newMap = list.stream()
                .filter(s -> Integer.parseInt(s.split(",")[1]) >= 24)
                .collect(Collectors.toMap(s -> s.split(",")[0],
                        s -> Integer.parseInt(s.split(",")[1])));
        System.out.println(newMap);
    }
}
运行结果:
练习三:

现在有两个ArratList集合,

第一个集合中存储6名男演员的名字和年龄

第二个集合中存储6名女演员的名字和年龄

姓名和年龄中间用逗号隔开,比如:张三,23

要求完成如下的操作

1.男演员只要名字为3个字的前两人

2.女演员只要姓杨的,并且不要第一个

3.把过滤后的男演员和女演员姓名合并到一起

4.将上一步的演员信息封装成Actor对象

5.将所有的演员对象都保存到List集合中

备注:演员类Actor,属性:name,age

代码:
java 复制代码
public class StreamTest3 {
    public static void main(String[] args) {
        /*
        现在有两个ArratList集合,
        第一个集合中存储6名男演员的名字和年龄
        第二个集合中存储6名女演员的名字和年龄
        姓名和年龄中间用逗号隔开,比如:张三,23
        要求完成如下的操作
        1.男演员只要名字为3个字的前两人
        2.女演员只要姓杨的,并且不要第一个
        3.把过滤后的男演员和女演员姓名合并到一起
        4.将上一步的演员信息封装成Actor对象
        5.将所有的演员对象都保存到List集合中
        备注:演员类Actor,属性:name,age
        */

        //创建集合并存储元素
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list1,"彭于晏,30","吴彦祖,31","周星驰,32",
                "古天乐,33","刘德华,34","周润发,35");
        Collections.addAll(list2,"杨紫,21","杨颖,22","刘亦菲,23",
                "高圆圆,24","杨超越,25","孙千,26");

        //1.男演员只要名字为3个字的前两人
        Stream<String> stream1 = list1.stream()
                .filter(s -> s.split(",")[0].length() == 3)
                .limit(2);

        //2.女演员只要姓杨的,并且不要第一个
        Stream<String> stream2 = list2.stream()
                .filter(s -> s.split(",")[0].startsWith("杨"))
                .skip(1);

        //3.把过滤后的男演员和女演员姓名合并到一起
        Stream<String> stream3 = Stream.concat(stream1, stream2);

        //4.将上一步的演员信息封装成Actor对象
        Stream<Actor> actorStream = stream3
                .map(s -> new Actor(s.split(",")[0], Integer.parseInt(s.split(",")[1])));

        //5.将所有的演员对象都保存到List集合中
        List<Actor> actorList = actorStream.collect(Collectors.toList());

        System.out.println(actorList);
    }
}
运行结果:
相关推荐
幽兰的天空38 分钟前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
梓仁沐白3 小时前
ubuntu+windows双系统切换后蓝牙设备无法连接
windows·ubuntu
Theodore_10224 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
网易独家音乐人Mike Zhou4 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
安静读书4 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
冰帝海岸5 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象5 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了6 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·6 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic6 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端