Google在今年發佈Android N開發者預覽版,一併宣佈開始支持Java 8。咱們終於能在Android開發中使用到Java8的一些語言特性了。目前支持:html
今天咱們就簡要學習lambda表達式。android
首先須要下載安裝JDK1.8。git
若是想在Android開發中使用lambda表達式,須要在Android Studio中配置Java 8開發環境。github
配置app的Gradle文件:app
android { defaultConfig { ... //開啓jack編譯 jackOptions { enabled true } } ... //將編譯選項設置爲Java1.8 compileOptions { targetCompatibility 1.8 sourceCompatibility 1.8 } }
出於種種緣由,可能咱們使用的JDK版本是1.7甚至更低,可是咱們又想學習使用lambda表達式,怎麼辦呢?Github上已經有開發者設計了兼容lambda表達式到Java7,6,5的開源庫retrolamda。至於如何在Android Studio中配置,在此就不囉嗦了。能夠參看Gradle Retrolambda Plugin。ide
看到下面的代碼,相信你們都會很是熟悉。這不就是給button設置監聽事件嘛。函數
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("TAG","按鈕被點擊,匿名內部類"); } });
分析上面的代碼,這是經過匿名內部類來設置Button的點擊監聽事件的。也就是說,咱們建立了一個實現了View.OnClickListener
接口的匿名類的對象。匿名內部類實現了onClick
方法。經過這個匿名類的對象,咱們在用戶點擊按鈕時,打印出日誌。學習
但是,你們有沒有發現。上面那段代碼,真正有用的就是Log.d("TAG","按鈕被點擊,匿名內部類");
這一行代碼,這就反映了使用匿名內部類的缺點:gradle
而lambda表達式很好的解決了這些問題:設計
button.setOnClickListener(view-> Log.d(TAG,"按鈕被點擊,lambda表達式"));
view-> Log.d(TAG,"按鈕被點擊,lambda表達式"));
就是咱們寫的第一個lambda表達式。
由上圖可知,lambda表達式一般以(argument)->(body)
這樣的格式書寫。
//省略參數類型 (arg1,arg2...) -> {body} //指定參數類型 (Type1 arg1,Type2 arg2...)->{body}
lambda表達式中,參數的類型可省略。Java編譯器根據表達式的上下文推導出參數的類型。就像上面圖中view
的類型是View
。
//零個 ()-> System.out.println("no argument"); //一個 x->x+1 //兩個 (x,y)->x+y //省略參數類型 View.OnClickListener oneArgument = view->Log.d(TAG,"one argument"); //指定參數類型 View.OnClickListener oneArgument = (View view)->Log.d(TAG,"one argument"); //多行語句 //返回類型是代碼塊返回的void View.OnClickListener multiLine = (View view)->{ Log.d(TAG,"multi statements"); Log.d(TAG,"second line"); } //返回類型是表達式主體語句的返回類型int (int x)->x+1
咱們都知道,Java是一種強類型語言。全部的方法參數都有類型,那麼lambda表達式是一種什麼類型呢?
View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { //... } }; button.setOnClickListener(listener);
如上所示,以往咱們是經過使用單一方法的接口來表明一個方法而且重用它。
在lambda表達式中,仍使用的和以前同樣的形式。咱們叫作函數式接口(functional interface)
如咱們以前button的點擊響應事件使用的View.OnClickListener
就是一個函數式接口。
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { ... public interface OnClickListener { void onClick(View v); } ... }
那究竟什麼樣的接口是函數式接口呢?
函數式接口是隻有一個抽象方法的接口。用做表示lambda表達式的類型。
Java8 API中新增了許多函數式接口:
接口名 | 參數 | 返回值 | 用途 |
---|---|---|---|
Predicate
|
T | boolean | 斷言 |
Consumer
|
T | void | 消費 |
Function<T,R> | T | R | 函數 |
Supplier
|
None | T | 工廠方法 |
UnaryOperator
|
T | T | 邏輯非 |
BinaryOperator
|
(T,T) | T | 二元操做 |