第207期 / January 5, 2015

研發新視界

分享到臉書!分享到維特!分享到噗浪!分享到Google+!分享到微博!轉寄友人友善列印

JDK 8 Lambda語法搭配Map應用介紹

作者/吳旻聰

[發表日期:2015/1/5]

在Oracle JDK 8 公布後新增了許多的功能及效能的改善,此次本文將介紹Lambda語法搭配Map一些便利的方法讓程式碼可以更容易閱讀且更加精簡。

1.forEach

以股票的例子來說,目前上市有幾檔股票而對應股票會有對應的Map存放成交價錢,在JDK8之前若要印出所有股票的成交價就必須使用以下兩種方法:


(1)


此方法主要是利用entrySet 傳回Map.entry的集合再用for迴圈尋訪這個集合印出各個Key 和 Value ,此種方法對程式的可讀性較差。

(2)



此方法是利用map.keySet()將各個key取出來後再利用此Key去Map內get出對應的Value,此方法較方法(1)程式可讀性更佳。

(3)JDK8:


此方法為JDK8結合Lamdba表示式的寫法就可以簡單的尋訪Map的Key和Value也兼顧程式的可讀性。

執行結果:



2. getOrDefault 和 putIfAbsent

以前在get某個Key值若不存在則給個預設值,在操作Map時若其對應的Key若不在Map則會回傳null,若直接對此回傳值進行存取將會產生null point exception的情況,為了避免這種情況通常會使用下列方式去判斷,get出來的內容是否為null。

以前面的例子來看若股票有成交的才將成交價放入Map內,若Map取不到則代表今天無成交,則使用個-1代表今天無成交。



而在JDK8新增了一個Method完成此件事情



若希望在取不到Value時同時將預設值給存入Map內則可以使用



最後將所有股票的成交價給印出:



3. compute

此Method提供指定的Key和指定的Lambda運算來決定Value的值,
接著上面例子來說,現在若要計算股票的收盤價錢是以當天最後一筆成交價作為當日的收盤價,若股票沒有成交價則使用前一天的收盤價錢做為收盤價。
假定前一日收盤價為:



而計算收盤價的method:



接著若要更利用compute計算所有股票的收盤價:



執行結果:


透過執行結果可以發現match_price_map.compute(stockKey,(key, value)-> getClosePrice(key,value));此運算將成交價的Map內各個Key和Value給取出並透過getClosePrice運算後將收盤價給存回Map中以Key:[HTC]來說因無成交價,所以,所以由yesterday_price_map中取出前一日收盤價Value:[130.5]且放回原本的Map中當作今日收盤價。

4. computeIfAbsent

現在利用費氏數列來說明computeIfAbsent此method所帶來的便利性,費氏數列的定義為:



在沒有使用map的情況下使用遞迴來計算帶入值所對應的解答以下為程式碼:



執行結果:

計算:f(6)
計算:f(5)
計算:f(4)
計算:f(3)
計算:f(2)
計算:f(2)
計算:f(3)
計算:f(2)
計算:f(4)
計算:f(3)
計算:f(2)
計算:f(2)
f(6) 結果:8
在沒使用Map時可以發現必須經過12次計算才能得出f(6)的結果,從結果看到有許多的值都重複計算,若加入Map即可減少重複計算的次數,程式如下:



執行結果:

JAVA 7 計算:f(6)
JAVA 7 計算:f(4)
JAVA 7 計算:f(2)
JAVA 7 計算:f(3)
JAVA 7 計算:f(5)
JAVA 7 f(6) 結果:8

透過執行結果可以發現計算次數由12次降到5次省掉許多重複計算的部分

接著若使用在JDK 8下可以使用computeIfAbsent 搭配lambda表示式來縮短程式碼,computeIfAbsent的作用是當Mp內Key沒有對應的Value時,進行指定的運算後並將結果Put進Map且將結果回傳。

程式碼如下:



執行結果:
Java8 計算 f(6)
Java8 計算 f(4)
Java8 計算 f(2)
Java8 計算 f(3)
Java8 計算 f(5)
JAVA 8 f(6) 結果:8

透過範例及執行結果來看,使用computeIfAbsent程式碼會較JDK 7以前的寫法簡短許多且兼顧效能。


結論

JDK 8 最大的不同就是導入Lambda的表示式也新增了許多方便的API提供大家在設計程式,可將以前必須實作許多行的程式縮短至一行內即完成也方便可讀性,JDK 8 還有許多新的功能像是JavaScript新引擎 [Nashorn]、新的Stream API、安全性增強功能等等,都是JDK8為程式設計師帶來許多更便利的方法來設計程式,還有許多未介紹的功能就由大家自行學習了。


參考資料

1. Java 8 API
2.CodeData 技術文章
3.Blog