stream(3)(徐建峰),2021Android面经

前面我们分析了Stream的执行顺序,对于垂直顺序特性来说,它的执行顺序会影响程序的性能,我们先看下面一段代码:

Stream.of("d2", "a2", "b1", "b3", "c")
    .map(s -> {
        System.out.println("map: " + s);
        return s.toUpperCase();
    })
    .filter(s -> {
        System.out.println("filter: " + s);
        return s.startsWith("A");
    })
    .forEach(s -> System.out.println("forEach: " + s));

上面代码执行结果为:

map:d2
filter: D2
map: a2
filter: A2
forEach:A2
map:b1
filter:B1
map:b3
filter:B3
map:c
filter:C

我们可以看到mapfilter都被执行5次,forEach被执行一次,如果我们把filter操作放到链条的前面那么执行结果是怎么样的呢?我们继续看代码:

Stream.of("d2", "a2", "b1", "b3", "c")
    .filter(s -> {
        System.out.println("filter: " + s);
        return s.startsWith("a");
    })
    .map(s -> {
        System.out.println("map: " + s);
        return s.toUpperCase();
    })
    .forEach(s -> System.out.println("forEach: " + s));

这段代码输出为:

filter:  d2
filter:  a2
map:     a2
forEach: A2
filter:  b1
filter:  b3
filter:  c

从输出结果我们可以看到map只被执行过一次,如果是在非常大数量元素上执行流操作,那么采用后面一种方式会极大地提高程序运行性能。

4. 更深入的探讨

在上面例子上再往深入探讨,我们增加一个sorted操作:

Stream.of("d2", "a2", "b1", "b3", "c")
    .sorted((s1, s2) -> {
        System.out.printf("sort: %s; %s\n", s1, s2);
        return s1.compareTo(s2);
    })
    .filter(s -> {
        System.out.println("filter: " + s);
        return s.startsWith("a");
    })
    .map(s -> {
        System.out.println("map: " + s);
        return s.toUpperCase();
    })
    .forEach(s -> System.out.println("forEach: " + s));

sort是一个特殊的中间操作,它是一个有状态的操作。为了在整个集合上排序在排序的时候必须维持一个状态。

我们先看下上面代码的执行结果:

sort:    a2; d2
sort:    b1; a2
sort:    b1; d2
sort:    b1; a2
sort:    b3; b1
sort:    b3; d2
sort:    c; b3
sort:    c; d2
filter:  a2
map:     a2
forEach: A2
filter:  b1
filter:  b3
filter:  c
filter:  d2

从上面执行结果我们可以得出sorted是水平执行的,上面的例子中sorted方法被执行了8次。但我们想一下,sorted方法有必要执行这么多次吗?排序后如果filter通不过那么这个元素不会留下来。

所以我们想如果把filter操作提前,提前把一些元素过滤掉,这样需要sort元素会减少性能就会提高。

我们先优化一下代码:

Stream.of("d2", "a2", "b1", "b3", "c", "a1").filter(s -> {
            System.out.println("filter: " + s);
            return s.startsWith("a");
        }).sorted((s1, s2) -> {
            System.out.printf("sort: %s; %s\n", s1, s2);
            return s1.compareTo(s2);
        }).map(s -> {
            System.out.println("map: " + s);
            return s.toUpperCase();
        }).forEach(s -> System.out.println("forEach: " + s));

上面例子中执行结果如下:

filter: d2
filter: a2
filter: b1
filter: b3
filter: c
filter: a1
sort: a1; a2
map: a1
forEach: A1
map: a2
forEach: A2

在这个例子中sorted只被调用一次,因为在前面执行filter后只剩下两个元素a1,a2

5. sorted水平执行特性

前面的中,我们发现在所有元素中都执行了filter操作才执行sorted方法,这个看起来跟前面讲的垂直执行特性相违背。

最后我还整理了很多Android中高级的PDF技术文档。以及一些大厂面试真题解析文档。

CodeChina开源项目地址:https://codechina.csdn.net/m0_60958482/android_p7

image

Android高级架构师之路很漫长,一起共勉吧!

t/m0_60958482/android_p7](https://codechina.csdn.net/m0_60958482/android_p7)**

[外链图片转存中…(img-5xgscOzR-1630941138148)]

Android高级架构师之路很漫长,一起共勉吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值