从命令式风格转变为函数式风格潜在的好处:运行时有能力在涉及效率的问题上替程序员做决定。
cleanNames
方法可以修改如下:cleanNames()
里面调换了操作的顺序,map()
操作被提到了filter()
的前面。
按照命令式的思路,本能地就会把筛选操作放在映射操作的前面,这样map
需要操作的列表会比较小,可以减少工作量。
很多函数式语言(包括Java 8乃至Functional Java框架)都提供了Stream
抽象。Stream
很多方面的行为都与集合相似,但它不像集合那样事先就备妥所有的值,而是需要的时候才让数据从源头“流”向目的地。
上例中数据源头是names
集合,最终目的地(或者叫终结操作)是collect()
。处在中间的map()
和filter()
都是缓求值(lazy)的操作,它们会被尽量地推迟执行。实际上在下游的终结操作“发出要求”之前,它们都不会产生任何结果。
聪明的运行时会重新安排缓求值操作的执行顺序。上例将在运行时的主持下调换其缓求值操作的顺序,让筛选操作先于映射操作执行,以取得最佳的运算效率。在使用Java平台上的各种函数式方案的时候,必须保证传给filter()
等函数的lambda块不存在副作用,否则可能导致无法预料的结果。
允许运行时发挥其优化能力的做法,再次印证了关于交出控制权的观点:放弃对繁琐细节的掌控,关注问题域,而非关注问题域的实现。