新聞中心
Java 8 還要有一陣才能發(fā)布,而且它會帶來一個(gè)我非常期待的語言特性:Lambda表達(dá)式。

成都創(chuàng)新互聯(lián)公司專注于陽東網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供陽東營銷型網(wǎng)站建設(shè),陽東網(wǎng)站制作、陽東網(wǎng)頁設(shè)計(jì)、陽東網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務(wù),打造陽東網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供陽東網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
不幸的是,其他的Java平臺大的新特性和模塊都已經(jīng)被推遲到了Java 9。不管怎樣,引入lambda表達(dá)式(如果你喜歡的話,也可以稱它為閉包),會使得Java的編程體驗(yàn)更棒。
還有一段時(shí)間的等待——不過Java的開發(fā)現(xiàn)在是開源的,我們現(xiàn)在可以看一看并且嘗試一下。我們開始吧!
[[69381]]
下載和安裝啟用了Lambda的Java 8
最開始,我還以為我需要自己去編譯Java 8,因?yàn)樗€沒有發(fā)布。不過,讓我驚奇的是,在http://jdk8.java.net/lambda/ 已經(jīng)提供了所有平臺可用的二進(jìn)制版本。因此我直接下載了***的開發(fā)者預(yù)覽版本,然后安裝在我的電腦上。
為了確保它是正常運(yùn)行的,我創(chuàng)建了一個(gè)LambadIntro類,它會輸出“Hello, World!”,編譯然后執(zhí)行它:
- ~ $ export JAVA_HOME=~/Devtools/Java/jdk1.8.0/
- ~ $ cd spikes/lambda-water
- ~ $ $JAVA_HOME/bin/javac src/net/jthoenes/blog/spike/lambda/LambdaIntro.java
- ~ $ $JAVA_HOME/bin/java -cp src net.jthoenes.blog.spike.lambda.LambdaIntro
- Hello from Java 8!
注意:我這里是用命令行來編譯和執(zhí)行的,因?yàn)镮DE現(xiàn)在還不支持Java 8。
非Lambda的方式
舉這么一個(gè)例子,假設(shè)我想要遍歷一個(gè)對象的列表。不過由于我的業(yè)務(wù)需求,我還需要取得列表項(xiàng)的值和索引。如果用現(xiàn)在版本的Java來做的話,我需要把實(shí)際的邏輯和索引放在一起進(jìn)行處理:
- List list = Arrays.asList("A", "B", "C");
- for (int index = 0; index < list.size(); index++) { String value = list.get(index); String output = String.format("%d -> %s", index, value);
- System.out.println(output);
- }
這樣會輸出
- 0 -> A
- 1 -> B
- 2 -> C
這樣其實(shí)也并不壞,但是我這幾行代碼里做了兩件事:控制列表的迭代以及進(jìn)行了一些(簡單)的業(yè)務(wù)邏輯處理。不過如果使用Lambda表達(dá)式的話,它可以幫助我把這兩者分開進(jìn)行處理。
eachWithIndex方法簽名
因此,我想實(shí)現(xiàn)一個(gè)eachWithIndex方法,它可以這樣被調(diào)用:
- List list = Arrays.asList("A", "B", "C");
- eachWithIndex(list,
- (value, index) -> {
- String output = String.format("%d -> %s", index, value);
- System.out.println(output);
- }
- );
這個(gè)方法接收兩個(gè)參數(shù)。***個(gè)參數(shù)是要處理的列表,第二個(gè)參數(shù)是一個(gè)lambda表達(dá)式或者閉包,它表示處理每個(gè)列表項(xiàng)的方法。你可以在第3行看到,這個(gè)lambda表達(dá)式接受兩個(gè)參數(shù):當(dāng)前值和當(dāng)前索引。這兩個(gè)參數(shù)都沒有類型聲明。Java 8 的編譯器會自動推導(dǎo)出參數(shù)的類型。在參數(shù)的后面,是一個(gè)->符號以及處理每個(gè)列表項(xiàng)的代碼塊。
注意:你需要在一個(gè)文本編輯器里編寫這個(gè)方法或者你需要忽略IDE提示的錯(cuò)誤信息。
實(shí)現(xiàn)eachWithIndex方法
為了使用Java 8 的lambda,你需要聲明一個(gè)功能接口。功能接口是一種特殊的接口,它只有一個(gè)方法——這個(gè)方法會被lambda表達(dá)式實(shí)現(xiàn)。在這個(gè)示例里,我需要聲明一個(gè)接收一個(gè)元素和索引并且沒有返回值的接口。因此,我定義了如下的接口:
- public static interface ItemWithIndexVisitor
{ - public void visit(E item, int index);
- }
通過這個(gè)接口,我現(xiàn)在可以實(shí)現(xiàn)eachWithIndex方法。
- public static
void eachWithIndex(List list, ItemWithIndexVisitor visitor) { - for (int i = 0; i < list.size(); i++) {
- visitor.visit(list.get(i), i);
- }
- }
這個(gè)方法使用了泛型參數(shù)
使用功能接口的一個(gè)好處是,Java里已經(jīng)有了很多的功能接口。想想關(guān)于 java.util.concurrent.Callableinterface的例子。它可以被當(dāng)作lambda表達(dá)式來使用,并且不需要修改 Callable的調(diào)用者的代碼。這樣使得大部分的JDK和框架默認(rèn)都能夠支持lambda表達(dá)式。
使用方法引用
另外一個(gè)來自于Lambda項(xiàng)目的很有用的東西是方法引用。它是一種復(fù)用已有的方法并且把它們打包成一個(gè)功能接口對象的方式。假設(shè)我們有如下的代碼:
- public static
void printItem(E value, int index) { - String output = String.format("%d -> %s", index, value);
- System.out.println(output);
- }
并且我想在eachWithIndex方法里調(diào)用它,那么我就可以在我的方法調(diào)用里使用::符號:
- eachWithIndex(list, LambdaIntro::printItem);
看起來很不錯(cuò),并且也很簡潔,對嗎?
總結(jié)
這樣就可以使得我的***個(gè)lambda表達(dá)式例子能夠運(yùn)行。等待了這么長的時(shí)間,能夠看到閉包運(yùn)行在我的Java程序里,我實(shí)在是太興奮了。Lambda表達(dá)式現(xiàn)在只是在開發(fā)者預(yù)覽的版本上可用。如果你想要了解更多的話,你可以去閱讀一下關(guān)于Lambda表達(dá)式的早期預(yù)案的評議,或者你也可以去看看Lambda項(xiàng)目的頁面。
我把整個(gè)實(shí)例代碼都上傳到gist上了。
英文原文:tataryn
編譯:ImportNew - 朱偉杰
網(wǎng)頁標(biāo)題:Java 8:Lambda表達(dá)式試水
網(wǎng)站網(wǎng)址:http://www.5511xx.com/article/ccoijdh.html


咨詢
建站咨詢
