美文网首页
Java8 Stream流式编程

Java8 Stream流式编程

作者: Java知识星球 | 来源:发表于2021-01-23 16:58 被阅读0次

    Stream介绍(摘抄)

    Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。JDK8新特性。

    Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

    这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选,排序,聚合等。

    Stream有以下特性及优点:

    • 无存储。Stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
    • 为函数式编程而生。对Stream的任何修改都不会修改背后的数据源,比如对Stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新Stream。
    • 惰式执行。Stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
    • 可消费性。Stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。

    流的创建

    • 集合 Collection.stream()
    • 静态方法 Stream.of
    • 数组 Arrays.stream
            // 流的创建
            // 1.集合
            List<String> list = Arrays.asList("a", "b", "c");
            Stream<String> listStream = list.stream();
            Stream<String> listParallelStream = list.parallelStream();
    
            // 2.数组
            Integer[] numberArray = {1,2,3,4};
            Stream<Integer> arrayStream1 = Arrays.stream(numberArray);
            Stream<Integer> arrayStream2 = Stream.of(numberArray);
            Stream<Integer> arrayParallelStream = Stream.of(numberArray).parallel();
    
            // 3.多个元素
            Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);
    
            // 4.单一元素
            Student student = new Student(1, "gxzhang", BigDecimal.ZERO);
            Stream<Student> studentStream = Stream.of(student);
    

    stream为串行流,parallelStream并行流可利用机器多核并发,效率更高,默认并发数为机器cpu核数。

    流的转换

    // 流的转换
    // 普通流转并行流
    Stream<String> parallel = listStream.parallel();
    // Stream<Integer> -> IntStream
    IntStream intStream2 = integerStream.mapToInt(value -> value.intValue());
    // IntStream -> Stream<Integer>
    Stream<Integer> integerStream3 = intstream.boxed();
    

    中间操作

    常用

    • filter(Predicate) 筛选流中某些元素

    • map(Function f) 接收流中元素,并且将其映射成为新元素,例如从student对象中取name属性

    • flatMap(Function f) 将所有流中的元素并到一起连接成一个流

    • peek(Consumer c) 获取流中元素,操作流中元素,与foreach不同的是不会截断流,可继续操作流

    • distinct() 通过流所生成元素的equals和hashCode去重

    • limit(long val) 截断流,取流中前val个元素

    • sorted(Comparator) 产生一个新流,按照比较器规则排序

    • sorted() 产生一个新流,按照自然顺序排序

    匹配

    • booelan allMatch(Predicate) 都符合
    • boolean anyMatch(Predicate) 任一元素符合
    • boolean noneMatch(Predicate) 都不符合

    查找元素

    • findFirst——返回第一个元素
    • findAny——返回当前流中的任意元素

    计数和极值

    • count——返回流中元素的总个数
    • max——返回流中最大值
    • min——返回流中最小值
            // 中间操作
            // filter:过滤值为为 "a" 的元素 filter的值为false时会被过滤
            list = listStream.filter(value -> "a".equals(value)).collect(Collectors.toList());
            // map 将值依次进行映射处理;将数据每个字符串后加‘-’符号
            list = listStream.map(value->value+"-").collect(Collectors.toList());
            // anyMatch 任意符合 返回布尔类型; 判断元素是否存在”a“
            boolean b = listStream.anyMatch(value -> "a".equals(value));
    
            // 流的扁平化
            // 将 数组["hello", "world"] 转变成 ["h","e","l","o","w","r","d"] 并将元素去重
            String[] strings = {"hello", "world"};
            // 这样返回的结果为 String[]数组类型的集合,而我们需要将List<String>类型的
            // 原因是因为map中将一个元素生成了多个元素返回了一个String[]数组类型
            List<String[]> collect = Stream.of(strings)
                    .map(word -> word.split(""))
                    .distinct()
                    .collect(Collectors.toList());
            // 采用flatmap进行流扁平化
            List<String> collect1 = Stream.of(strings).
                    flatMap(word -> Arrays.stream(word.split("")))
                    .distinct()
                    .collect(Collectors.toList());
    

    终止操作

    • foreach(Consumer c) 遍历操作
    • collect(Collector) 将流转化为其他形式
    • max(Comparator) 返回流中最大值
    • min(Comparator) 返回流中最小值
    • count 返回流中元素综述

    Collectors 具体方法

    • toList List<T> 把流中元素收集到List
    • toSet Set<T> 把流中元素收集到Set
    • toCollection Coolection<T> 把流中元素收集到Collection中
    • groupingBy Map<K,List<T>> 根据K属性对流进行分组
    • partitioningBy Map<boolean, List<T>> 根据boolean值进行分组
            // 终止操作
            // 流的遍历
            listStream.forEach(value-> System.out.println(value));
            listStream.forEach(value-> System.out.println(value));
            listStream.forEach(System.out::println);
            listStream.forEach(value -> {
                // 多条语句用花括号
                System.out.println("二哈");
                System.out.println(value);
            });
            // 归约,计算数和;0 为identity初始值,a将被赋值为上次计算结果(初始为identity值),b流中元素
            int sum = intstream.reduce(0, (a, b) -> a + b);
            // 收集 将处理后的结果返回对应的类型数据
            List<Integer> list1 = integerStream.collect(Collectors.toList());
            // 其他
            // 最大值
            int max = intstream.max().getAsInt();
            // 最小值
            int min = intstream.min().getAsInt();
            // 和
            intstream.sum();
    

    注意事项

    流一旦执行了终止操作就不再可用,必须需要重新获取流。

    流式编程为语法糖,最终编译后执行效果和不加糖是一致的,只是语法糖帮我们提升了编程效率和常用操作的最优实现。

    以上案例仅为方便说明用法,不可直接执行。

    流的常用api以上已说明,案例只简单列举了常用的api用法,可根据简单介绍很容易上手。

    欲练此功,必先多敲✊

    相关文章

      网友评论

          本文标题:Java8 Stream流式编程

          本文链接:https://www.haomeiwen.com/subject/dgjuzktx.html