lambdas for_Lambdas:来到您附近的Java 8!
lambdas for
什么是Lambda?
Lambda表達(dá)式是一種匿名函數(shù),可以在方法中內(nèi)聯(lián)編寫(xiě),并且可以在使用表達(dá)式的任何地方使用。 有時(shí)您可能會(huì)發(fā)現(xiàn)它們被稱(chēng)為閉包,盡管我在下面解釋了對(duì)該參考的一些注意事項(xiàng)。 像普通的Java方法一樣,它具有參數(shù)和可以執(zhí)行的主體。 Java 8中令人興奮的新功能之一是lambda表達(dá)式,該表達(dá)式已定義為JSR 335的一部分。
添加lambda表達(dá)式將使Java更輕松地支持函數(shù)式編程技術(shù)和高階函數(shù)。 這并不是說(shuō)突然變成一夜之間成為諸如Haskell之類(lèi)的奇特而深?yuàn)W的語(yǔ)言,但是它將朝著與諸如C#,Ruby或python之類(lèi)的語(yǔ)言一樣的方向發(fā)展。 也就是說(shuō),為有意義的功能樣式提供部分支持,但仍允許您使用命令式技術(shù),例如可變變量。
基本語(yǔ)法
這是一個(gè)lambda表達(dá)式,該表達(dá)式使數(shù)字遞增1:
x -> x + 1如您所見(jiàn),表達(dá)式以參數(shù)開(kāi)頭,以參數(shù)主體結(jié)尾,并用箭頭將兩者分開(kāi)。 您也可以顯式鍵入?yún)?shù),在參數(shù)上放置類(lèi)型注釋或具有多個(gè)參數(shù)。 如果您想執(zhí)行這些操作,則需要將參數(shù)放在方括號(hào)中,例如:
// Explicit Types(Integer x) -> x + 1// Multiple Arguments(Integer x1, Integer x2) -> x1 + 1// Annotations:(Integer x1, @SuppressWarnings("unused") Integer x2) -> x1 + 1到目前為止,所有的lambda主體都是表達(dá)式,但是您也可以像常規(guī)方法一樣,將主體編寫(xiě)為一系列語(yǔ)句。
(x) -> { x += 5; System.out.println(x); return x; };由于lambda是正則表達(dá)式,因此您可以將其視為正則表達(dá)式。 例如,您可以將它們分配給變量,將它們作為參數(shù)傳遞給其他方法。
// a method: public static void useFunc(IntFun f) { System.out.println(f.apply(2)); } // in code IntFun inc = x -> x + 1; useFunc(inc); useFunc(x -> x + 1);類(lèi)型?
由于這是Java,因此即使不是所有這些“ x”參數(shù)都標(biāo)記為“整數(shù)”,所有這些函數(shù)仍然是靜態(tài)類(lèi)型的。 幸運(yùn)的是,Java 7中方法句柄的引入提供了一種引用方法本身的方法。 這意味著您的函數(shù)并不需要全部實(shí)現(xiàn)某個(gè)通用接口,它們可以是被認(rèn)為是“函數(shù)接口”的任何東西。
引用規(guī)范草案,“功能接口是僅具有一種抽象方法的接口,因此表示單個(gè)功能協(xié)定。” 這些也可以用首字母縮寫(xiě)詞“ SAM”來(lái)表示,它代表“單一抽象方法”。 例如:
interface Runnable { void run(); } interface Function { public R apply(A a); } interface IntFun extends Function {} // equals is defined by java.lang.Object, so this only has one abstract method interface Comparator { boolean equals(Object obj); int compare(T o1, T o2); }因此,通過(guò)確保使用保持這些約束的接口,當(dāng)前正在編寫(xiě)/正在編寫(xiě)的任何API都可以被lambda使用。 Guava庫(kù)是一個(gè)已經(jīng)鼓勵(lì)有限的功能編程風(fēng)格的示例API。
更有趣的例子
經(jīng)驗(yàn)豐富的函數(shù)式程序員會(huì)意識(shí)到map函數(shù),該函數(shù)會(huì)為您返回一個(gè)新列表,其中每個(gè)值都由函數(shù)更改。 在番石榴世界中,此功能稱(chēng)為“變換”。 這是您今天可以編寫(xiě)的一些Java代碼示例,使用它來(lái)遞增列表:
Collection result = transform(newArrayList(1, 2, 3), new Function() { @Override public Integer apply(Integer x) { return x + 1; } });這是一個(gè)高階函數(shù)的示例,即以函數(shù)為參數(shù)或返回函數(shù)的函數(shù)。 轉(zhuǎn)換函數(shù)使迭代集合和構(gòu)建新集合的過(guò)程抽象化,從而可以編寫(xiě)更多抽象的高級(jí)代碼。 不幸的是,由于我們受到了很多行噪聲的干擾,因此在一定程度上克服了可讀性的優(yōu)勢(shì),但是如果您使用lambda重寫(xiě)它:
Collection result = transform(newArrayList(1, 2, 3),x -> x + 1);另一個(gè)常用的高階函數(shù)是濾波函數(shù)。 如果為它提供一個(gè)集合和一個(gè)謂詞,它將返回一個(gè)新集合,其中包含該謂詞對(duì)其適用的舊集合中的元素。 這是一個(gè)以匿名內(nèi)部類(lèi)樣式和lambda表達(dá)式方式編寫(xiě)的代碼示例。
Collection threeAndFive = filter(newArrayList(1, 3, 5), new Predicate() { @Override public boolean apply(Integer x) { return x > 2; } }); Collection threeAndFiveByLambda = filter(newArrayList(1, 3, 5),x -> x > 2);方法參考
當(dāng)然,您可能已有一個(gè)已經(jīng)定義了許多方法的現(xiàn)有代碼庫(kù),您希望使用它們代替lambda。 目前,這在Java中也可以使用匿名內(nèi)部類(lèi)實(shí)現(xiàn),但同樣麻煩。 除了提供lambda表達(dá)式外,JSR 335還提出了一些語(yǔ)法糖,以使此過(guò)程更容易。 您可以使用'::'符號(hào)作為已編寫(xiě)的現(xiàn)有方法的方法參考。 這是前面的示例,但是使用了方法參考:
// Existing method public static boolean greaterThanTwo(Integer x) { return x > 2; } // prints [3, 5] System.out.println(filter(newArrayList(1,3,5),LambdasExample::greaterThanTwo));他們真的是閉包嗎?
在引言中,我提到過(guò)lambda表達(dá)式可以稱(chēng)為closures 。 這意味著一個(gè)函數(shù)能夠引用其正常范圍之外的變量,或者被封閉在周?chē)秶淖杂勺兞恐稀?
int value = 5; IntFun addValue = x -> x + value;在此代碼示例中,“ addValue”功能能夠引用周?chē)秶械拿麨椤?value”的變量,盡管對(duì)此有一些警告。 如果您之前編寫(xiě)過(guò)匿名內(nèi)部類(lèi),那么您會(huì)回想起它們只能引用周?chē)淖兞?#xff0c;這些變量被標(biāo)記為final,即未分配給它們。 這里的限制是相似的,只是它已被概括為最終有效的限制 。 簡(jiǎn)而言之,您可以引用未分配給多個(gè)變量的變量。 原理是,如果變量被標(biāo)記為final或可以被標(biāo)記為final而不引入編譯器錯(cuò)誤,則該變量實(shí)際上是final。
嘗試和鏈接
lambdas規(guī)范的早期草案審核的一部分已經(jīng)在線發(fā)布,并且如果您想了解正在發(fā)生的事情的來(lái)龍去脈,那么這可能對(duì)您來(lái)說(shuō)很有趣。 如果您有興趣嘗試編寫(xiě)一些lambda代碼,則已經(jīng)有二進(jìn)制快照 。 這些內(nèi)容經(jīng)常更新,如果您想了解lambda內(nèi)部結(jié)構(gòu)的實(shí)質(zhì),可以嘗試構(gòu)建源代碼 。 關(guān)于使用二進(jìn)制代碼編寫(xiě)代碼的唯一警告是,由于它仍處于草稿版本中,并且仍在使用“#”運(yùn)算符而不是“ ::”作為方法參考語(yǔ)法,因此仍然存在一些bug。
摘要
這是對(duì)Java 8的Lambda表達(dá)式的某些概念的介紹,因此簡(jiǎn)化了所涉及的一些問(wèn)題,但對(duì)于讀者來(lái)說(shuō),了解即將發(fā)生的事情應(yīng)該足夠了。 很高興看到Oracle在事物的語(yǔ)言方面引入了一些有用的更改,這種更改已經(jīng)停滯了一段時(shí)間。
翻譯自: https://www.javacodegeeks.com/2013/07/lambdas-coming-to-a-java-8-near-you.html
lambdas for
總結(jié)
以上是生活随笔為你收集整理的lambdas for_Lambdas:来到您附近的Java 8!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 备案域名网站(备案域名网)
- 下一篇: 安卓手机悬浮窗怎么开(安卓手机悬浮)