從命令式風格轉變為函數式風格潛在的好處:運行時有能力在涉及效率的問題上替程序員做決定。
cleanNames
方法可以修改如下:cleanNames()
里面調換了操作的順序,map()
操作被提到了filter()
的前面。
按照命令式的思路,本能地就會把篩選操作放在映射操作的前面,這樣map
需要操作的列表會比較小,可以減少工作量。
很多函數式語言(包括Java 8乃至Functional Java框架)都提供了Stream
抽象。Stream
很多方面的行為都與集合相似,但它不像集合那樣事先就備妥所有的值,而是需要的時候才讓數據從源頭“流”向目的地。
上例中數據源頭是names
集合,最終目的地(或者叫終結操作)是collect()
。處在中間的map()
和filter()
都是緩求值(lazy)的操作,它們會被盡量地推遲執行。實際上在下游的終結操作“發出要求”之前,它們都不會產生任何結果。
聰明的運行時會重新安排緩求值操作的執行順序。上例將在運行時的主持下調換其緩求值操作的順序,讓篩選操作先于映射操作執行,以取得最佳的運算效率。在使用Java平臺上的各種函數式方案的時候,必須保證傳給filter()
等函數的lambda塊不存在副作用,否則可能導致無法預料的結果。
允許運行時發揮其優化能力的做法,再次印證了關于交出控制權的觀點:放棄對繁瑣細節的掌控,關注問題域,而非關注問題域的實現。