Stream API学习

stream,是Java函数式编程的主角。stream并不是某种数据结构,它只是数据源的一种视图。这里的数据源可以是一个数组,Java容器或I/O channel等。正因如此要得到一个stream通常不会手动创建,而是调用对应的工具方法,比如:
调用Collection.stream()或者Collection.parallelStream()方法
调用Arrays.stream(T[] array)方法

常见的stream接口继承关系如图:

Stream API学习

stream的特点

  • 无存储。stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。

  • 为函数式编程而生。对stream的任何修改都不会修改背后的数据源,比如对stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新stream。

  • 惰式执行。stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。

  • 可消费性。stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。

对stream的操作分为两类,中间操作(intermediate operations)和结束操作(terminal operations)

  • 中间操作总是会惰式执行,调用中间操作只会生成一个标记了该操作的新stream,仅此而已。

  • 结束操作会触发实际计算,计算发生时会把所有中间操作积攒的操作以pipeline的方式执行,这样可以减少迭代次数。计算完成之后stream就会失效。

区分中间操作和结束操作最简单的方法,就是看方法的返回值,返回值为stream的大都是中间操作,否则是结束操作。

stream方法使用

ForEach

属于结束操作,对stream里的每个元素进行操作,void forEach(Consumer<? super T> action);

        Stream<String> stream = Stream.of("Success", "is", "not", "final");
        //常规写法
        stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        //lambda表达式写法
        stream.forEach(s -> System.out.println(s));
        //方法引用写法
        stream.forEach(System.out::println);
上一篇:forEach用法与map用法区别


下一篇:el-tree二次封装,已选城市处理为树形结构