Stream基础知识整理:特性-生命周期-执行-Collector

Stream特性

        1)不存储元素:元素通过Spliterator来遍历获取

        2)不改变源对象:返回持有结果新的Stream

        3)操作延迟执行:在需要结果的时候执行

Stream生命周期

        Stream的生命周期:创建-->中间操作-->终端操作(终止操作)

        1)创建

        集合获取:Collection.stream()

        数组创建:Arrays.stream(new String[2])

        数值创建:Stream.of(1,2,3)

        生成:Stream.generate(Supplier<T> s),属于无限流,需设定停止条件

        迭代:Stream.iterate(final T seed, final UnaryOperator<T> f),属于无限流,需设定停止条件。UnaryOperator继承Function,输入和输出属同类型,输入是前一个的输出。

        连接:Stream.concat(Stream<? extents T> a, Stream<? extents T> b),两个Stream连接一起生成新的Stream。

        Stream也提供了Builder方式创建,如:Stream.builder().add(1).add(2).build()

        2)中间操作

        中间操作分为两大类:无状态操作(StatelessOp)、有状态操作(StatefulOp)

        StatelessOp:filter\map\mapToInt\mapToLong\mapToDouble

                                \flatMap\flatMapToInt\flatMapToLong\flatMapToDouble\peek

        StatefulOp:distinct\sorted\limit\skip

        3)终端操作

        终端操作有:ForEachOp、MatchOp、FindOp、ReduceOp和toArray\collect\count

        ForEachOp:forEach\forEachOrdered

        MatchOp:anyMatch\allMatch\noneMatch

        FindOp:findFirst\findAny

        ReduceOp:reduce\min\max

Stream执行

        1) 顺序流

        同步执行,在当前线程执行,不做线程转换

        2) 并行流

        异步执行,Fork多个线程执行,例如Collection的Spliterator中的trySplit的单个线程执行数量是1<<10个,小于1<<10就在同一个线程执行。

FunctionalInterface

        Function接口,数学表达就是 y = f(x),x:输入值 f:操作 y:输出结果,输入值通过操作输出1个结果。其它的FuncationalInterface都是Function接口的变形,方面使用。

例如:

        输入为null,就是Supplier,数学表达就是 y = f()

        输出为null,就是Consumer,数学表达就是 f(x)

        输出为boolean,就是Predicate,数学表达就是 boolean = f(x)

再如:

        输入值变成两个,就是Bi**类接口

        输入x或输出y变成某种特定类型就是**To或者To**或者**To**等类型

        举例:Comparator就是 int = f(x,y),输入x,y两个值,输出1个int类型结果

        返回值>0则x>y   返回值==0则x==y   返回值<0则x<y

        FuncationalInterface特点就是接口中只有1个为实现方法,可以有多个方法,除了未实现的方法,其它的都必须有default修饰。目的就是结合lambda来使用,写出简洁的语句。

Collector

        1)归集

        Collectors.toCollection:Stream转成指定类型的集合

ArrayList<String> result = Stream
                .of("1","2","3","4","5","6","7","8","9")
                .collect(Collectors.toCollection(ArrayList::new));

        Collectors.toConcurrentMap:Stream转成ConcurrentMap,是ConcurrentHashMap

        ConcurrentMap<String, String> result1 = Stream
                .of("1","2","3","4","5","6","7","8","9")
                .collect(Collectors.toConcurrentMap(key -> "key_" + key, value -> "value_" + value));

        Collectors.toList:Stream转成List,是ArrayList

List<String> result2 = Stream
                .of("1","2","3","4","5","6","7","8","9")
                .collect(Collectors.toList());

        Collectors.toMap:Stream转成Map,是HashMap

        Map<String, String> result3 = Stream
                .of("1","2","3","4","5","6","7","8","9")
                .collect(Collectors.toMap(key -> "key_" + key, value -> "value_" + value));

        Collectors.toSet:Stream转成Set,是HashSet

Set<String> result4 = Stream
                .of("1","2","3","4","5","6","7","8","9")
                .collect(Collectors.toSet());

        2)统计

        Collectors.summarizingDouble:Stream转成DoubleSummaryStatistics

        Collectors.summarizingInt:Stream转成IntSummaryStatistics

        Collectors.summarzingLong:Stream转成LongSummaryStatistics

        计算:均值、个数、最大值、最小值、总和等

        IntSummaryStatistics result5 = Stream
                .of("1","2","3","4","5","6","7","8","9")
                .collect(Collectors.summarizingInt(Integer::valueOf));
        result5.getAverage();
        result5.getCount();
        result5.getMax();
        result5.getMin();
        result5.getSum();

        Collectors.summingDouble:Stream转成double,计算总和

        Collectors.summingInt:Stream转成int,计算总和

        Collectors.summingLong:Stream转成long,计算总和

        int result6 = Stream
                .of("1","2","3","4","5","6","7","8","9")
                .collect(Collectors.summingInt(Integer::valueOf));

        Collectors.averagingDouble:Stream转成double,计算均值

        Collectors.averagingInt:Stream转成double,计算均值

        Collectors.averagingLong:Stream转成double,计算均值

double result7 = Stream
                .of("1","2","3","4","5","6","7","8","9")
                .collect(Collectors.averagingInt(Integer::valueOf));

         Collectors.counting:Stream转成long,计算个数

long result8 = Stream
                .of("1","2","3","4","5","6","7","8","9")
                .collect(Collectors.counting());

        Collectors.maxBy:Stream转成Optional,包含最大值

        Collectors.minBy:Stream转成Optional,包含最小值

        Optional<String> result9 = Stream
                .of("1", "2", "3", "4", "5", "6", "7", "8", "9")
                .collect(Collectors.minBy(Comparator.comparingInt(Integer::parseInt)));

        3)分组\分区

        Collectors.groupingBy:Stream转成Map,是HashMap,Key计算结果,Value是根据计算结果分组

        Collectors.groupingByConcurrent:Stream转成ConcurrentMap,是ConcurrentHashMap

        Collectors.partitioningBy:Stream转成Map,是Partition,Key是true和false,Value是根据断言结果分区

        Map<String, List<String>> result10 = Stream
                .of("1", "2", "3", "4", "5", "6", "7", "8", "9")
                .collect(Collectors.groupingBy(value -> value));

        4)接合

        Collectors.joining:Stream转成String,数据中间按给定符号隔开,前后可加不同符号

        String result11 = Stream
                .of("1", "2", "3", "4", "5", "6", "7", "8", "9")
                .collect(Collectors.joining("-", "前", "后"));

        5)归约

        Collectors.reducing:Stream转成相应类型

String result12 = Stream
                .of("1", "2", "3", "4", "5", "6", "7", "8", "9")
                .collect(Collectors.reducing("0", (s, s2) -> s + s2));

        6)映射

        Collectors.mapping:Stream转成另一个类型,可再次做处理

        List<String> result13 = Stream
                .of("1", "2", "3", "4", "5", "6", "7", "8", "9")
                .collect(Collectors.mapping(value -> value + "_mapping", Collectors.toList()));

       7)收集再处理

        Collectors.collectingAndThen:可多次处理数据

        List<String> result14 = Stream
                .of("1", "2", "3", "4", "5", "6", "7", "8", "9")
                .collect(Collectors.collectingAndThen(Collectors.toList(), strings -> {
                    strings.forEach(System.out::print);
                    return Arrays.asList("aa", "bb", "cc");
                }));
        result14.forEach(System.out::print);

学习Stream同步执行的设计逻辑

Stream同步执行的设计逻辑:Pipeline-Terminal-Sink_~yportnE的博客-CSDN博客Pipeline管道或流水线,设计类似双向链表,ReferencePipeline主要实现了Stream接口,Stream是暴露给用户的接口。AbstractPipeline主要实现了BaseStream接口。它们的继承关系如图:ReferencePipeline实现类有三种:Head-链表头、StatelessOp-无状态操作、StatefullOp-有状态操作。无状态操作和有状态操作都属于中间操作,Head是stream操作创建的第一个Stream,记录了数据...https://blog.csdn.net/zhiyuan263287/article/details/124528432

猜你喜欢

转载自blog.csdn.net/zhiyuan263287/article/details/124540708