面試中一定會問的JAVA8新特性——Lambda表達式

編程語言 泛函編程 Java虛擬機 技術 程序員須知 2017-08-02

面試中一定會問的JAVA8新特性——Lambda表達式

Lambda表達式(也稱為閉包)是整個Java 8發行版中最受期待的在Java語言層面上的改變,Lambda允許把函數作為一個方法的參數(函數作為參數傳遞進方法中),或者把代碼看成數據:函數式程序員對這一概念非常熟悉。在JVM平臺上的很多語言(Groovy,Scala,……)從一開始就有Lambda,但是Java程序員不得不使用毫無新意的匿名類來代替lambda。

關於Lambda設計的討論佔用了大量的時間與社區的努力。可喜的是,最終找到了一個平衡點,使得可以使用一種即簡潔又緊湊的新方式來構造Lambdas。在最簡單的形式中,一個lambda可以由用逗號分隔的參數列表、–>符號與函數體三部分表示。例如:

1、Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ));

請注意參數e的類型是由編譯器推測出來的。同時,你也可以通過把參數類型與參數包括在括號中的形式直接給出參數的類型。在某些情況下lambda的函數體會更加複雜,這時可以把函數體放到在一對花括號中,就像在Java中定義普通函數一樣。例如:

Arrays.asList( "a", "b", "d" ).forEach( e -> {

System.out.print( e );

System.out.print( e );

} );

Lambda可以引用類的成員變量與局部變量(如果這些變量不是final的話,它們會被隱含的轉為final,這樣效率更高)。例如,下面兩個代碼片段是等價的:

String separator = ",";

Arrays.asList( "a", "b", "d" ).forEach(

( String e ) -> System.out.print( e + separator ) );


final String separator = ",";

Arrays.asList( "a", "b", "d" ).forEach(

( String e ) -> System.out.print( e + separator ) );

Lambda可能會返回一個值。返回值的類型也是由編譯器推測出來的。如果lambda的函數體只有一行的話,那麼沒有必要顯式使用return語句。下面兩個代碼片段是等價的:

Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );

Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> {

int result = e1.compareTo( e2 );

return result;

} );

語言設計者投入了大量精力來思考如何使現有的函數友好地支持lambda。最終採取的方法是:增加函數式接口的概念。函數式接口就是一個具有一個方法的普通接口。像這樣的接口,可以被隱式轉換為lambda表達式。java.lang.Runnable與java.util.concurrent.Callable是函數式接口最典型的兩個例子。在實際使用過程中,函數式接口是容易出錯的:如有某個人在接口定義中增加了另一個方法,這時,這個接口就不再是函數式的了,並且編譯過程也會失敗。為了克服函數式接口的這種脆弱性並且能夠明確聲明接口作為函數式接口的意圖,Java 8增加了一種特殊的註解@FunctionalInterface(Java 8中所有類庫的已有接口都添加了@FunctionalInterface註解)。讓我們看一下這種函數式接口的定義:

@FunctionalInterface

public interface Functional {

void method();

}

需要記住的一件事是:默認方法與靜態方法並不影響函數式接口的契約,可以任意使用:

@FunctionalInterface

public interface FunctionalDefaultMethods {

void method();

default void defaultMethod() {

}

}

Lambda是Java 8最大的賣點。它具有吸引越來越多程序員到Java平臺上的潛力,並且能夠在純Java語言環境中提供一種優雅的方式來支持函數式編程。更多詳情可以參考官方文檔。

http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

面試中一定會問的JAVA8新特性——Lambda表達式

Java創始人之一:詹姆斯·高斯林

相關推薦

推薦中...