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);
    }
}
运行结果:
相关推荐
间彧13 小时前
Spring Boot集成Spring Security完整指南
java
间彧13 小时前
Spring Secutiy基本原理及工作流程
java
数据智能老司机14 小时前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
Java水解14 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
数据智能老司机15 小时前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
c8i16 小时前
django中的FBV 和 CBV
python·django
c8i16 小时前
python中的闭包和装饰器
python
洛小豆16 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学17 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole17 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端