熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java8和Scala中的Lambda表達式

2013-11-23 19:35:24  來源: Java核心技術 
    Java 終於要支持Lambda表達式!自年以來Lambda表達式已經在Lambda項目中被支持在那時候Lambda表達式仍被稱為Java閉包在我們進入一些代碼示例以前先來解釋下為什麼Lambda表達式在Java程序員中廣受歡迎
   
    為什麼使用Lambda表達式
   
    Lambda表達式通常使用在圖形用戶界面(GUI)的開發中一般來說GUI編程將程序行為和事件做連接比如當用戶按下一個按鈕(觸發一個事件)你的程序就需要去執行某些行為可能是將一些數據儲存到一個數據存儲器中在Swing中可以使用ActionListener來實現
   
    class ButtonHandler implements ActionListener {
   
    public void actionPerformed(ActionEvent e)
   
    {
   
    //do something
   
    }
   
    }
   
    class UIBuilder {
   
    public UIBuilder() {
   
    buttonaddActionListener(new ButtonHandler())
   
    }
   
    }
   
    這個例子表明了 ButtonHandler 類作為一個回調替換的用法在這裡 ButtonHandler 類僅包含 ActionListener 接口定義的 actionPerformed 方法我們可以使用匿名內部類來簡化代碼
   
    class UIBuilder {
   
    public UIBuilder() {
   
    buttonaddActionListener(new ActionListener() {
   
    public void actionPerformed(ActionEvent event) {
   
    //do something
   
    }
   
    })
   
    }
   
    }
   
    這樣代碼簡潔多了更仔細的去看代碼時就會發現我們還創建一個只生成一個實例的類而這個實例也僅僅持有一個獨立的方法這恰好是Lambda表達式所能解決的其中一類問題
   
    Lambda表達式代替函數
   
    一個lambda表達式從字面上講就是一個函數它定義了一個函數的輸入參數和函數體Java 中的lambda表達式語法尚未確定不過大致應該類似這個樣子的
   
    (type parameter) > function_body 一個具體的例子
   
    (String s String s> slength() slength()
   
    這個lambda表達式用來計算兩個字符串的長度差還有一些擴展的語法比如避免參數的類型定義(我們馬上見看到例子)還有使用{和}來支持多行定義
   
    Collectionssort()
   
    方法是lambda表達的理想例子它允許我們將字符串按照長度排序
   
    List<String> list = ArrayasList(loooooong short tiny
   
    Collectionssort(list (String s String s> slength() slength())
   
    > tiny short loooooong
   
    所以不像現在java必須要求的向sort方法輸入一個已經實現的Comparator(比較器)而是傳送一個lambda表達式我們就可以得到相同的結果
   
    Lambda表達式代替閉包
   
    lambda表達式有許多有趣的特性其中之一是它們是閉包一個閉包允許函數訪問直接詞法作用域之外的變量
   
    String outer = java (String s> slength() outerlength()
   
    在例子中lambda表達式訪問了字符串 outer 這個作用域之外定義的變量對於內聯閉包來說這是很難做到的
   
    Lambda表達式也支持類型推論
   
    類型推論是java 引入的但它同樣適用於lambda表達式簡單來說類型推論意味著程序員可以在任意一個編譯器能夠自動推斷出類型的地方省略類型定義如果類型推論能夠應用到前面的排序lambda表達式上那麼它就能寫成下面的樣子
   
    List<String> list = ArraysasList(…)
   
    Collectionssort(list (s s> slength()slength())
   
    就像你所見到的一樣參數s和s的類型被省略了因為編譯器知道list是一個字符串集合它知道被用來作為比較器的lambda表達式必定是相同的類型因此這個類型不需要顯式地聲明即使你有這麼做的自由
   
    類型推論的主要優勢就是減少樣板代碼如果編譯器可以為我們識別類型為什麼我們必須自己定義它們
   
    珍愛Lambda表達式遠離匿名內部類
   
    我們來體會下為何lambda表達式和類型推論有助於簡化我們前面所提到的回調例子
   
    class UIBuilder {
   
    public UIBuilder() {
   
    buttonaddActionListener(e > //process ActionEvent e)
   
    }
   
    }
   
    我們下載直接傳送一個lambda表達式進入 addActionListener 方法來代替前面定義的持有回調方法的類除了減少模板代碼和提高可讀性以外它使我們直接表達我們唯一感興趣的事情處理事件
   
    在我們了解lambda表達式更多優勢之前先來看看在Scala中的lambda表達式副本
   
    Scala中的Lambda表達式
   
    在函數式編程中函數是基本的構造塊Scala融合了java中的面向對象編程和函數式編程在Scala中一個lambda表達式是種叫做函數或者函數文本Scala中的函數屬於一等公民它們可以被分配給vals或者vars(最終變量或者非最終變量)它們可以作為其他函數的參數也可以組合成新的函數
   
    在Scala中一個函數文本寫成如下形式
   
    (argument) => //funtion body
   
    舉例來說前面提到的java 用來計算兩個字符串長度差的 lambda 表達式在Scala中寫作如下
   
    (s: String s :String) => slength s
   
    length Scala中的函數文本也是閉包它可以訪問在直接詞法作用域之外定義的變量
   
    val outer = val myFuncLiteral = (y: Int) => y * outer  val result = myFuncLiteral()  > 這個例子結果是
   
    正如你所見我們將函數文本分配給了變量 myFuncLiteral
   
    java 的lambda表達式和Scala的函數文本在語法和語義上的相似性是十分明顯的從語義上講它們是相同的而語法上的唯一不同就是箭頭符號(java > scala =>)和我們沒有提到的簡化符號
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27132.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.