Java 8給Java帶來了一場變革。很明顯,這個版本是過去十年以來推出的最具份量的Java更新,其中囊括了海量新特性,包括默認方法、方法與構造函數引用以及Lambda函數等等。
其中最有趣的一項特性當數全新java.util.streamAPI,它作為Javadoc狀態存在,能夠對元素流進行函數式操作,例如在集合中進行map-reduce變換。
將這個新API與Lambda表達式相結合,我們就得到了一條簡潔但卻強大的語法,能夠對應用程序中的代碼進行大幅簡化。1

將這個新API與Lambda表達式相結合,我們就得到了一條簡潔但卻強大的語法,能夠對應用程序中的代碼進行大幅簡化。
就以表面上看起來相當簡單的集合過濾任務為例。在這一實例中,我們如下所示創建Message Collection type:
創建一個Messages Collection
List messages = new ArrayList(); messages.add(new Message("aglover", "foo", 56854)); messages.add(new Message("aglover", "foo", 85)); messages.add(new Message("aglover", "bar", 9999)); messages.add(new Message("rsmith", "foo", 4564));
在這個集合中,我打算將delay(第三個構造函數參數)在3000秒以上作為條件對Message進行全面過濾。在Java 8之前的版本中,大家可以用以下方式表達這類邏輯:
傳統過濾方式
for (Message message : messages)
if (message.delay > 3000)
System.outln(message);
不過在Java 8中,這項工作將變得更加簡單明了。集合如今支持stream方法,它能夠將底層數據結構轉化為可重復的對象流,從而實現使用Lambda表達式的全新函數式操作。大多數此類操作都可以被串連起來。這些可串連方法被稱為intermediate,那些無法被串連的方法則被表示為terminal。
簡要來講,Lambda表達式與匿名類基本相似,只不過摒棄了大量語法限制。舉例來說,如果大家在查看Javadoc以尋找Stream中filter方法的對應參數,各位會發現它擁有一個Predicate type。不過我們不需要像在Java 8之前的版本中那樣利用匿名類來實現這一對接。因此,Predicate Lambda表達式能夠過濾掉所有數值高于3000的條目,如下所示:
Lambda表達式
x -> x.delay > 3000
其中的x正是被傳送至集合流內每一個值的參數,而->符號右側的所有內容都作為表達式估值。將這些結合起來,就成了Java 8中的處理方式:
Lambda表達式流
messages.stream().filter(m -> m.delay > 3000).forEach(item -> System.outln(item));
有趣的是,由于Java 8中的其它一些新特性,我們還可以對forEach的Lambda表達式進行進一步簡化:
Lambda表達式流還能進一步簡化
messages.stream().filter(m -> m.delay > 3000).forEach(System.out::println);
由于forEach Lambda表達式的參數僅僅單純作用于println,Java 8現在允許我們直接對參數進行整體對接。
之前我曾經提到過,集合流允許大家將各個Lambda表達式串連起來—在上面的例子中,filter方法屬于一項intermediate方法,而forEach則是一項terminal方法。其它能夠為函數程序員快速識別出的intermediate方法還包括:map、flatMap以及reduce等,這里就不一一列舉了。
具體來講,我希望找到Message當中所有延遲周期超過3000秒的條目并計算它們的總計延遲時長。如果沒有函數魔法作為輔助,我只能如下進行:
普通Java寫法
long totalWaitTime = 0; for (Message message : messages)
if (message.delay > 3000)
totalWaitTime += message.delay;
然而隨著Java 8的面世與大量新函數的出現,大家可以實現更為精致的代碼結構,具體如下:
文藝Java 8寫法
long totWaitTime = messages.stream().filter(m -> m.delay > 3000).mapToLong(m -> m.delay).sum();
請注意我將filter與mapToLong方法進行串連的方式,再加上一條terminal sum。順便說一句,sum方法需要使用一種特殊的映射方法類型才能產生原始type集合,例如mapToLong以及mapToInt等等。
函數式編程作為一大核心語言特性,能夠為開發者帶來令人嘆為觀止的強大構建能力。雖然大部分此類技術已經能夠在各類第三方庫(例如Guava)以及JVM語言(例如Scala與Groovy)中找到,但將這些關鍵特性融入Java仍然能夠吸引更為廣泛的開發者受眾、并給未來的開發前景帶來深遠影響。
毫無疑問,Java 8的出現讓Java在通往完美的道路上再度邁出一大步。