Java8的新特性-Stream

2020-10-03  本文已影响0人  devKen

java的stream api,首先我们应该意识到它是做了两个重要的抽象,stream(流)代表了数据元素的有限或无限的顺序,stream pipeline(流管道)则代表这些元素的一个多级计算。第一个抽象,方便了我们从另外一种视角观察集合(collection)的元素,以便可以对其进行加强操作。另外一个抽象,则是具体聚合操作层次的加强。所以,对于这个api的使用,首先应该是从集合生成stream(第一步抽象),再通过它的各种中间操作api,对元素进行计算,最后有一个终止操作进行确定。下面我们就从生成stream开始说起。

静态工厂方法:stream.of(); 数组输出方法Arrays.stream();列表输出方法list.stream()。

对于基础类型现在有三个对应的包装流:IntStream;LongStream;DoubleStream.这三个包装流有着和常规流效果一样的操作api。

生成stream后就是根据自己需求执行中间操作了。执行中间操作只是从一个流生成另外一个流。对source stream,无论中间操作怎么玩,最后的结果如何,都没有影响和改动。常用的中间操作有如下几个。

1.map/flatMap(映射)

它的作用是把输入流的每个元素映射到输出流的每个元素。

2.filter (过滤)

它的作用是加上一层条件进行过滤。

3.distinct(去重)

4.sorted(排序)

5.limit/skip

limit返回流前n个元素;skip是跳过前n个元素。

6.peek

对每个元素执行操作后返回一个新的stream

在我们根据自己的需求执行完了上面一个或者多个中间操作后,一定要以一个终止操作结束。这里就会发现stream其实是lazy的,它只有到终止操作才开始计算。这使得无限stream成了可能?

常用的终止操作有forEach,collect。

forEach 它需要你传一个lambda表达式进行循环计算。collect 转换成特定集合。

总的来说,使用stream可以在某些情况下简化你的操作,并且看起来很干练。因为使用了lambda。但是滥用的话也会增加代码不易读。首先,我们必须认识到,stream并不改善性能,它只是提供另外一种写法,本质上和之前的同样作用的写法作用一样。当你尝试使用stream时,一定不能完全抛弃之前的写法。最优的选择时两个都试试,再决定。

参考测试代码

public static void main(String[] args) {  
       List<String> stringCollection = new ArrayList<>();
        stringCollection.add("ddd2");
        stringCollection.add("aaa2");
        stringCollection.add("bbb1");
        stringCollection.add("aaa1");
        stringCollection.add("bbb3");
        stringCollection.add("ccc");
        stringCollection.add("bbb2");
        stringCollection.add("ddd1");


        // filtering

        stringCollection
                .stream()
                .filter((s) -> s.startsWith("a"))
                .forEach(System.out::println);

        // "aaa2", "aaa1"


        // sorting

        stringCollection
                .stream()
                .sorted()
                .filter((s) -> s.startsWith("a"))
                .forEach(System.out::println);

        // "aaa1", "aaa2"


        // mapping

        stringCollection
                .stream()
                .map(String::toUpperCase)
                .sorted((a, b) -> b.compareTo(a))
                .forEach(System.out::println);

        // "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1"


        // matching

        boolean anyStartsWithA = stringCollection
                .stream()
                .anyMatch((s) -> s.startsWith("a"));

        System.out.println(anyStartsWithA);      // true

        boolean allStartsWithA = stringCollection
                .stream()
                .allMatch((s) -> s.startsWith("a"));

        System.out.println(allStartsWithA);      // false

        boolean noneStartsWithZ = stringCollection
                .stream()
                .noneMatch((s) -> s.startsWith("z"));

        System.out.println(noneStartsWithZ);      // true


        // counting

        long startsWithB = stringCollection
                .stream()
                .filter((s) -> s.startsWith("b"))
                .count();

        System.out.println(startsWithB);    // 3


        // reducing

        Optional<String> reduced =
                stringCollection
                        .stream()
                        .sorted()
                        .reduce((s1, s2) -> s1 + "#" + s2);

        reduced.ifPresent(System.out::println);
        // "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"


    }
上一篇下一篇

猜你喜欢

热点阅读