我最近閱讀了Brian Goetz的《 Lambda的狀況》 ,在閱讀了該文章之后,我想嘗試使用Java 8 Lambda表達式。 Brian在他的文章中繼續描述了將一種方法稱為“功能”接口的接口。 功能接口幾乎總是用作匿名類,其中ActionListener是規范示例。 這些“功能性”界面是lambda表達式的最初目標,主要目標是刪除許多使用它們的樣板或儀式。 當我在Guava庫上編寫系列文章時,立即想到了Function接口,它是嘗試使用lambda表達式的主要候選對象。
我的目標很簡單,從我的Guava Futures博客中進行單元測試(它大量使用Function接口)并將其轉換為使用lambda表達式。 雖然我將介紹與所舉示例有關的lamba表達式的結構,但本文并非是有關Java 8 lambda表達式的教程。 而是記錄了我在Java中使用lambda表達式的首次嘗試。
Lambda表達式
第一個示例是對Futures.chain方法的測試,該方法將Function作為參數之一:
Function<List<String>, ListenableFuture<List<Person>>> queryFunction =new Function<List<String>, ListenableFuture<List<Person>>>() {@Overridepublic ListenableFuture<List<Person>> apply(final List<String> ids) {return dbService.getPersonsByIdAsync(ids);}};ListenableFuture<List<String>> indexSearch = luceneSearcher.searchAsync('firstName:martin');
ListenableFuture<List<Person>> results = Futures.chain(indexSearch,queryFunction,executorService);
使用lamba表達式,現在看起來像:
Function<List<String>, ListenableFuture<List<Person>>> queryFunction =ids ->(dbService.getPersonsByIdAsync(ids));ListenableFuture<List<String>> indexSearch = luceneSearcher.searchAsync('firstName:martin');ListenableFuture<List<Person>>results = Futures.chain(indexSearch, queryFunction,executorService);
請記住,在上面的代碼示例中,兩個突出顯示的部分是等效的。 讓我們看一下第2行,并說明它如何與第一個代碼示例中的1-7行匹配
-
ids
是apply方法的輸入,并且對應于第一個代碼示例中第4行的final List<String> ids
參數。 lamba表達式的類型是從使用它的上下文中推斷出來的,因此我們不需要為ids
參數重復它們。 - 然后是箭頭(->)令牌,它是當前形式的Java 8 lambda表達式的常規語法的一部分
- 然后,我們得到了lambda的主體(dbService.getPersonsByIdAsync(ids)),該主體是一個方法調用,該方法返回一個ListenableFuture,進而產生一個Person對象列表。 請注意,我們不必放入return語句,因為這是一個表達式,可以求值并返回。
下一個示例是測試中的實用程序方法,該方法通過將匿名Callable實例傳遞到ExecutorService中來返回ListenableFutures:
private ListenableFuture<List<Person>> getPersonsByFirstNameFuture(final String firstName, final boolean error) {
return executorService.submit(new Callable<List<Person>>() {@Overridepublic List<Person> call() throws Exception {startSignal.await();if (error) {throw new RuntimeException('Ooops!');}List<String> ids = luceneSearcher.search('firstName:' + firstName);return dbService.getPersonsById(ids);}});
}
這是使用lambda表達式的等效項:
private ListenableFuture<List<Person>> getPersonsByFirstNameFuture(final String firstName, final boolean error) {return executorService.submit(() -> {startSignal.await();if (error) {throw new RuntimeException('Ooops!');}List<String> ids = luceneSearcher.search('firstName:' + firstName);return dbService.getPersonsById(ids);});
}
在此示例中,沒有輸入參數,因此表達式在第2行以空括號()開頭。存在->標記,但是在此示例中,主體包含由{…}包圍的多個語句。 由于存在多個語句,因此在第7行需要顯式return語句。
運行Java 8的環境
我當前的筆記本電腦是MacBook Pro,因此我需要設置一個環境以運行具有lambda支持的Java 8。 這是我采取的步驟:
- 在VirtualBox上安裝了LinuxMint 12。
- 創建一個目錄并與LinuxMint來賓共享
- 安裝了Java 8的開發人員預覽版 。
- 為了從現有的maven項目中獲取源代碼并測試源代碼,我運行了
mvn jar:jar jar:test-jar
并將生成的jar文件放在共享目錄中 - 將所有依賴項放在共享目錄中(guava,lucene,h2和junit)
- 重新編寫單元測試以使用lambda,并從命令行運行新測試
結論
盡管要發布支持lambda的Java 8尚需時日,但開發人員預覽版中提供的功能似乎很有希望。感謝您的時間,一如既往地歡迎提出意見和建議
資源資源
- Lambda的狀態,第4部分
- Java 8開發人員預覽
- 這篇文章的源代碼
- 番石榴項目首頁
- Guava博客系列的源代碼
參考:來自我們的JCG合作伙伴 Bill Bejeck的Guava Functions&Java 8 Lambdas,來自“ 隨機編碼思考”博客。
翻譯自: https://www.javacodegeeks.com/2012/11/guava-functions-java-8-lambdas.html