您好,登錄后才能下訂單哦!
Scala中的Lambda表達式是什么以及為什么使用Lambda表達式,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
Java8終于要支持Lambda表達式!自2009年以來Lambda表達式已經在Lambda項目中被支持。在那時候,Lambda表達式仍被稱為Java閉包。下面億速云小編來講解下為什么使用Lambda表達式?Scala中的Lambda表達式是什么?
為什么使用Lambda表達式
Lambda表達式通常使用在圖形用戶界面(GUI)的開發中。一般來說,GUI編程將程序行為和事件做連接。比如,當用戶按下一個按鈕(觸發一個事件),你的程序就需要去執行某些行為,可能是將一些數據儲存到一個數據存儲器中。在Swing中,可以使用ActionListener來實現:
classButtonHandlerimplementsActionListener{
publicvoidactionPerformed(ActionEvente)
{
//dosomething
}
}
classUIBuilder{
publicUIBuilder(){
button.addActionListener(newButtonHandler());
}
}
這個例子表明了ButtonHandler類作為一個回調替換的用法。在這里ButtonHandler類僅包含ActionListener接口定義的actionPerformed方法。我們可以使用匿名內部類來簡化代碼:
classUIBuilder{
publicUIBuilder(){
button.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEventevent){
//dosomething
}
})
}
}
這樣代碼簡潔多了。更仔細的去看代碼時,就會發現我們還創建一個只生成一個實例的類,而這個實例也僅僅持有一個獨立的方法。這恰好是Lambda表達式所能解決的其中一類問題。
Lambda表達式代替函數
一個lambda表達式從字面上講就是一個函數。它定義了一個函數的輸入參數和函數體。Java8中的,lambda表達式語法尚未確定,不過大致應該類似這個樣子的:
(typeparameter)->function_body一個具體的例子:
(Strings1,Strings2)->s1.length()-s2.length();
這個lambda表達式用來計算兩個字符串的長度差。還有一些擴展的語法,比如避免參數的類型定義(我們馬上見看到例子)還有使用{和}來支持多行定義。
Collections.sort()
方法是lambda表達的理想例子。它允許我們將字符串按照長度排序:
List
Collections.sort(list,(Strings1,Strings2)->s1.length()-s2.length());
>"tiny","short","loooooong".
所以,不像現在java必須要求的向sort方法輸入一個已經實現的Comparator(比較器)而是傳送一個lambda表達式我們就可以得到相同的結果。
Lambda表達式代替閉包
lambda表達式有許多有趣的特性。其中之一是,它們是閉包。一個閉包允許函數訪問直接詞法作用域之外的變量。
Stringouter="java8"(Strings1)->s1.length()-outer.length()
在例子中,lambda表達式訪問了字符串outer這個作用域之外定義的變量。對于內聯閉包來說這是很難做到的。
Lambda表達式也支持類型推論
類型推論是java7引入的但它同樣適用于lambda表達式。簡單來說,類型推論意味著程序員可以在任意一個編譯器能夠自動推斷出類型的地方省略類型定義。如果類型推論能夠應用到前面的排序lambda表達式上,那么它就能寫成下面的樣子:
List
Collections.sort(list,(s1,s2)->s1.length()-s2.length());
就像你所見到的一樣,參數s1和s2的類型被省略了。因為編譯器知道list是一個字符串集合,它知道被用來作為比較器的lambda表達式必定是相同的類型。因此,這個類型不需要顯式地聲明,即使你有這么做的自由。
類型推論的主要優勢就是減少樣板代碼,如果編譯器可以為我們識別類型,為什么我們必須自己定義它們。
珍愛Lambda表達式,遠離匿名內部類
我們來體會下,為何lambda表達式和類型推論有助于簡化我們前面所提到的回調例子:
classUIBuilder{
publicUIBuilder(){
button.addActionListener(e->//processActionEvente)
}
}
我們下載直接傳送一個lambda表達式進入addActionListener方法來代替前面定義的持有回調方法的類。除了減少模板代碼和提高可讀性以外,它使我們直接表達我們唯一感興趣的事情:處理事件。
在我們了解lambda表達式更多優勢之前,先來看看在Scala中的lambda表達式副本。
Scala中的Lambda表達式是什么
在函數式編程中,函數是基本的構造塊。Scala融合了java中的面向對象編程和函數式編程。在Scala中,一個lambda表達式是種叫做"函數"或者"函數文本".Scala中的函數屬于一等公民。它們可以被分配給vals或者vars(最終變量或者非最終變量),它們可以作為其他函數的參數,也可以組合成新的函數。
在Scala中一個函數文本寫成如下形式:
(argument)=>//funtionbody
舉例來說,前面提到的java用來計算兩個字符串長度差的lambda表達式,在Scala中寫作如下:
(s1:String,s2:String)=>s1.length-s2.
lengthScala中的函數文本也是閉包。它可以訪問在直接詞法作用域之外定義的變量。
valouter=10valmyFuncLiteral=(y:Int)=>y*outervalresult=myFuncLiteral(2)>20這個例子結果是20.
正如你所見,我們將函數文本分配給了變量myFuncLiteral.
java8的lambda表達式和Scala的函數文本在語法和語義上的相似性是十分明顯的。從語義上講它們是相同的,而語法上的唯一不同就是箭頭符號(java8->,scala=>)和我們沒有提到的簡化符號。
關于Scala中的Lambda表達式是什么以及為什么使用Lambda表達式問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。