Java 基础进阶篇(十二):Stream 流常用方法总结

文章目录

  • 一、Stream流概述
  • 二、获取Stream流
    • 2.1 集合获取 Stream 流
    • 2.2 数组获取 Stream 流
  • 三、中间方法
  • 四、终结方法
  • 五、Stream流的综合应用
  • 六、收集Stream流

一、Stream流概述

在 Java8 中,得益于 Lambda 所带来的函数式编程, 引入了一个全新的 Stream 流概念。

目的:用于简化集合和数组操作的API。

Stream 流思想:先得到集合或者数组的 Stream 流(就是一根传送带);把元素放上去;然后就用这个 Stream 流简化的 API 来方便的操作元素

Stream 流的三类方法

① 获取 Stream 流:创建一条流水线,并把数据放到流水线上准备进行操作。
② 中间方法:流水线上的操作,一次操作完毕之后,还可以继续进行其他操作。
③ 终结方法:一个Stream流只能有一个终结方法,是流水线上的最后一个操作。

二、获取Stream流

Stream 操作集合或者数组的第一步是先得到 Stream 流,然后才能使用流的功能。

2.1 集合获取 Stream 流

Collection 系列集合:默认方法 stream​() 生成流。

Collection<String> list = new ArrayList<>();
Stream<String> s1 = list.stream();

Map 系列集合使用 stream() 方法获取键流、值流、键值对的流。

Map<String, Integer> map = new HashMap<>();
// 键流
Stream<String> s2 = map.keySet().stream();
// 值流
Stream<Integer> s3 = map.values().stream();
// 键值对
Stream<Map.Entry<String, Integer>> s4 = map.entrySet().stream();

2.2 数组获取 Stream 流

String[] strs = {"张三丰", "灭绝师太", "东方不败"};
Stream<String> s5 = Arrays.stream(strs);
Stream<String> s6 = Stream.of(strs);

三、中间方法

Stream 流的中间方法,即中间操作方法,也称为非终结方法。常用的 API 如下:

注意:调用完成后返回新的 Stream 流可以继续使用,支持链式编程;在 Stream 流中无法直接修改集合、数组中的数据

四、终结方法

Stream 流的终结方法,即终结操作方法。常用的 API 如下:在这里插入代码片

注意:终结操作方法,调用完成后流就无法继续使用了,原因是不会返回 Stream 流。

五、Stream流的综合应用

案例1:从集合中找到姓张,且名称长度是3的姓名。

public class StreamDemo1 {
    public static void main(String[] args) {
        ArrayList<String> names = new ArrayList<>();
        Collections.addAll(names, "张三丰", "张无忌", "张三", "李四", "李明", "张强");
   
        // 从集合中找到姓张,且名称长度是3的姓名。
        names.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("张");
            }
        }).filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length()==3;
            }
        }).forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        // Lambda 化简
        names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==3).forEach(s-> System.out.println(s));
        names.stream().filter(s -> s.startsWith("张")&&s.length()==3).forEach(System.out::println);
    }
}

案例2:测试 map 加工方法

public class StreamDemo2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "张三丰", "张无忌", "张三", "李四", "李明", "张强");
        
        // map加工方法
        // new Function<String, String>() 第一个参数原材料,第二个参数是加工后的结果。
        // 1. 需求1:给集合元素的前面都加上一个:黑马的:
        list.stream().map(new Function<String, String>() {
            @Override
            public String apply(String s) { // 形参类型是第一个参数,方法返回类型是第二个参数
                return "黑马的" + s;
            }
        });
        // Lambda 化简
        list.stream().map(s -> "黑马的" + s).forEach(System.out::println);


        // 2. 需求2:把所有的名称 都加工成一个学生对象。
        list.stream().map(new Function<String, Student>() {
            @Override
            public Student apply(String s) {
                return new Student(s);
            }
        });
        list.stream().map(s -> new Student(s)).forEach(System.out::println);
        list.stream().map(Student::new).forEach(System.out::println); // 构造器引用,方法引用
    }
}

案例3:测试合并流

public class StreamDemo3 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "张三丰", "张无忌", "张三", "李四", "李明", "张强");

        // 合并流
        Stream<String> s1 = list.stream().filter(s -> s.startsWith("张"));
        Stream<String> s2 = Stream.of("java1", "java2");
        // public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
        Stream<String> s3 = Stream.concat(s1, s2);
        //s3.forEach(System.out::println);
        s3.distinct().forEach(System.out::println); // 去重后输出

        // distinct 依赖 hasCode 和 equals 方法
        ArrayList<Student> students = new ArrayList<>();
        Collections.addAll(students, new Student("张无忌"), new Student("张无忌"), new Student("张三丰"), new Student("张三丰"), new Student("李有田"));
        students.stream().distinct().forEach(System.out::println); // Student{name='张无忌'}, Student{name='张三丰'}Student{name='李有田'}
    }
}

六、收集Stream流

收集 Stream 流,就是把 Stream 流操作后的结果数据转回到集合或者数组中去。

Stream流只是方便操作集合/数组的手段,得到集合/数组才是开发中的目的

Stream 流的收集方法:

Collectors 工具类提供了具体的收集方式:

public class StreamDemo5 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张三丰");
        
        Stream<String> s1 = list.stream().filter(s -> s.startsWith("张"));
        List<String> zhangList = s1.collect(Collectors.toList());
        //List<String> zhangList = s1.toList(); // jdk16新添加方法 这种写法,返回不可变集合
        zhangList.add("新添加的元素"); //  如果添加元素 s1.toList(),方法会报错
        System.out.println(zhangList); // [张无忌, 张强, 张三丰, 张三丰, 新添加的元素]

        // 注意:流只能使用一次,若要重新使用流,需要重新定义
        Stream<String> s2 = list.stream().filter(s -> s.startsWith("张"));
        Set<String> zhangSet = s2.collect(Collectors.toSet()); // 收集成Set
        System.out.println(zhangSet); // [张强, 张三丰, 张无忌]

        Stream<String> s3 = list.stream().filter(s -> s.startsWith("张"));
        Object[] arrs = s3.toArray();// 收集成数组
        System.out.println(Arrays.toString(arrs)); // [张无忌, 张强, 张三丰, 张三丰]

        // 拓展:收集成指定流,如 String 流
        Stream<String> s4 = list.stream().filter(s -> s.startsWith("张"));
        String[] array = s4.toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });// 收集成数组

        // String[] array = s4.toArray( value -> new String[value] );
        // String[] array = s4.toArray(String[]::new);
        System.out.println(Arrays.toString(array)); // [张无忌, 张强, 张三丰, 张三丰]
    }
}

文章参考:Java入门基础视频教程,java零基础自学就选黑马程序员Java入门教程(含Java项目和Java真题)

版权声明:本文为博主作者:Xiu Yan原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/weixin_43819566/article/details/130537949

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2024年1月3日
下一篇 2024年1月3日

相关推荐