Java Lambdas简介
Java 8的主題是lambdas。 我已經(jīng)注意到,對(duì)于許多Java程序員來(lái)說(shuō),lambda都是非常難的材料。 因此,讓我們嘗試對(duì)它們有一個(gè)基本的了解。
首先,lambda到底是什么? Lambda是一個(gè)匿名函數(shù),與常規(guī)函數(shù)不同,它沒(méi)有綁定到標(biāo)識(shí)符(即,它沒(méi)有名稱)。 這些函數(shù)可以作為參數(shù)傳遞給其他函數(shù)(稱為高階函數(shù))。
假設(shè)我們的應(yīng)用程序必須從系統(tǒng)的不同位置寫入一堆文件。 我們不想每次都處理已檢查的異常[請(qǐng)參閱“ 例外:已檢查和未檢查”以獲取有關(guān)已檢查的異常的更多信息]。 因此,我們決定編寫一個(gè)低級(jí)的writeToFile函數(shù),該函數(shù)將打開(kāi)FileWriter并將其傳遞給可以安全地寫入文件的函數(shù)。
使用此低級(jí)函數(shù),我們編寫以下代碼。
writeToFile("todo.txt", new FileWriteFunction() {@Overridepublic void apply(Writer file) throws IOException {file.write("learn about lambdas\n");file.write("learn stream API\n");} })我們傳遞給writeToFile的對(duì)象是FileWriteFunction的匿名實(shí)現(xiàn)[是匿名的,因?yàn)槲覀儧](méi)有將其命名為類]。 它具有單個(gè)功能,因此可以有效地傳遞匿名功能。 在Java的世界中,這些有時(shí)稱為回調(diào) 。 可能您以前至少使用過(guò)幾次,也許沒(méi)有引起注意。
該匿名對(duì)象實(shí)際上是lambda。 但這顯然不像傳遞函數(shù)。 語(yǔ)法非常笨拙。 這正是Java 8中的變化。
有了Java 8中對(duì)lambda的語(yǔ)法支持,代碼的讀取就像我們傳遞函數(shù)一樣。 使用Java 8 lambda,我們將上述代碼重寫如下。
writeToFile("todo.txt", file -> {file.write("learn about lambdas\n");file.write("learn stream API\n"); })這樣更好 它強(qiáng)調(diào)重要的代碼,并隱藏了大部分笨拙的部分。
通常,lambda與閉包可互換使用(即詞匯功能)。 雖然它們都是匿名函數(shù),但是閉包的定義是它是包含綁定變量的函數(shù)。 即,閉包包括一個(gè)引用表,該表包含對(duì)局部變量的引用。
例如,如果我們接受要寫入文件的參數(shù)data ,則使用閉包。
void save(String data) {writeToFile("file.db", file -> file.write(data) ); }匿名內(nèi)部類限制對(duì)最終變量的訪問(wèn),而閉包提供對(duì)任何變量的訪問(wèn)。 但是,變量實(shí)際上是閉包的最終變量,因此無(wú)法將其重新分配。
那lambdas的編譯呢? Java 8是否僅使用一種方法就匿名內(nèi)部類僅提供了一勺語(yǔ)法糖?
不是,不是 的確,它允許對(duì)任何單方法匿名內(nèi)部類使用lambda語(yǔ)法。 但是lambda并沒(méi)有被編譯成內(nèi)部類。 相反,編譯器在定義的類中輸出lambda$方法,并使用invokedynamic調(diào)度該調(diào)用。
因此,現(xiàn)在您知道了如何在Java 8中使用lambda。雖然lambda本身非常有用,但在將它們應(yīng)用于集合時(shí)更是如此。
新的Stream API通過(guò)為集合提供功能更強(qiáng)大的API來(lái)提供迭代器的替代方案: java.util.stream.Stream 。 Stream上最值得注意的功能是: collect , filter , map和reduce 。
從一個(gè)簡(jiǎn)單的例子開(kāi)始,這里是如何對(duì)列表中的所有數(shù)字求和。
asList(1,2,3,4,5).stream().reduce(0, (acc, value) -> acc + value) // => 15通過(guò)從零開(kāi)始將每個(gè)值加到累加器上,可以減少序列。 為了進(jìn)行比較,通常會(huì)編寫一個(gè)循環(huán)。
int acc = 0; for (int n : asList(1,2,3,4,5))acc += n; acc // => 15繼續(xù)求和僅求奇數(shù)。 首先我們filter奇數(shù),然后reduce 。
asList(1,2,3,4,5).stream().filter(Predicates::odd).reduce(0, (acc, n) -> acc + n) // => 9filter的參數(shù)是我使用的Predicates類中對(duì)靜態(tài)odd函數(shù)的函數(shù)引用。 顧名思義,這是一個(gè)布爾函數(shù),用于測(cè)試數(shù)字是否為奇數(shù)。
到目前為止,一切都很好。 現(xiàn)在,假設(shè)我們要將一厘米大小的列表轉(zhuǎn)換為以英寸為單位的等效大小。 我們?yōu)榇耸褂胢ap 。
List<Inch> inches = centimeters.stream().map(Centimeter::toInches).collect(Collectors.toList())通過(guò)將toInches函數(shù)應(yīng)用到centimeters集合中的每個(gè)項(xiàng)目,將centimeters映射為英寸。
從本質(zhì)上講, Stream是連續(xù)的。 它用于描述要應(yīng)用于集合的操作。 但是要獲得結(jié)果,必須收集數(shù)據(jù)。 這就是collect功能的目的。 它將流的元素簡(jiǎn)化為可變?nèi)萜?#xff08;例如,列表)。
使用Stream API和lambda可以大大簡(jiǎn)化用于集合的代碼,并使代碼更具表現(xiàn)力。 與使用破壞性操作(例如forEach )相比,首選使用非破壞性操作(例如map , filter )使代碼更易于推理。
而已! 這些是您需要了解的Java 8中的lambda(和閉包)的基礎(chǔ)知識(shí)。當(dāng)然,關(guān)于lambda的內(nèi)容還有很多要寫的,但這是另一篇文章。
翻譯自: https://www.javacodegeeks.com/2013/10/introduction-to-java-lambdas.html
總結(jié)
以上是生活随笔為你收集整理的Java Lambdas简介的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2024 款奥迪 Q8 / SQ8 SU
- 下一篇: 优酷与 BBC Studios 合作,将