前言
Google在今年發(fā)布Android N開發(fā)者預(yù)覽版,一并宣布開始支持Java 8。我們終于能在Android開發(fā)中使用到Java8的一些語言特性了。目前支持:
- 默認方法
- lambda表達式
- 多次注解
今天我們就簡要學(xué)習(xí)lambda表達式。
配置開發(fā)環(huán)境
首先需要下載安裝JDK1.8。
如果想在Android開發(fā)中使用lambda表達式,需要在Android Studio中配置Java 8開發(fā)環(huán)境。
配置app的Gradle文件:
- 開啟jack編譯選項
- 設(shè)置編譯選項兼容到1.8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
android { defaultConfig { ... //開啟jack編譯 jackOptions { enabled true } } ... //將編譯選項設(shè)置為Java1.8 compileOptions { targetCompatibility 1.8 sourceCompatibility 1.8 } } |
出于種種原因,可能我們使用的JDK版本是1.7甚至更低,但是我們又想學(xué)習(xí)使用lambda表達式,怎么辦呢?Github上已經(jīng)有開發(fā)者設(shè)計了兼容lambda表達式到Java7,6,5的開源庫retrolamda。至于如何在Android Studio中配置,在此就不啰嗦了。可以參看Gradle Retrolambda Plugin。
第一個lambda表達式
看到下面的代碼,相信大家都會非常熟悉。這不就是給button設(shè)置監(jiān)聽事件嘛。
1
2
3
4
5
6
|
button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Log.d( "TAG" , "按鈕被點擊,匿名內(nèi)部類" ); } }); |
分析上面的代碼,這是通過匿名內(nèi)部類來設(shè)置Button的點擊監(jiān)聽事件的。也就是說,我們創(chuàng)建了一個實現(xiàn)了 View.OnClickListener
接口的匿名類的對象。匿名內(nèi)部類實現(xiàn)了 onClick
方法。通過這個匿名類的對象,我們在用戶點擊按鈕時,打印出日志。
可是,大家有沒有發(fā)現(xiàn)。上面那段代碼,真正有用的就是 Log.d("TAG","按鈕被點擊,匿名內(nèi)部類"); 這一行代碼,這就反映了使用匿名內(nèi)部類的缺點:
- 可讀性差,不能直接明了的體現(xiàn)我們的意圖。
- 啰嗦,一行邏輯代碼卻有幾行模板代碼。
而lambda表達式很好的解決了這些問題:
1
|
button.setOnClickListener(view-> Log.d(TAG,"按鈕被點擊,lambda表達式")); |
view-> Log.d(TAG,"按鈕被點擊,lambda表達式"));
就是我們寫的第一個lambda表達式。
lambda表達式通常以 (argument)->(body)
這樣的格式書寫。
1
2
3
4
5
|
//省略參數(shù)類型 (arg1,arg2...) -> {body} //指定參數(shù)類型 (Type1 arg1,Type2 arg2...)->{body} |
lambda表達式中,參數(shù)的類型可省略。Java編譯器根據(jù)表達式的上下文推導(dǎo)出參數(shù)的類型。就像上面圖中 view 的類型是 View 。
lambda表達式的結(jié)構(gòu)
- 參數(shù)可以是零個或多個
- 參數(shù)類型可指定,可省略(根據(jù)表達式上下文推斷)
- 參數(shù)包含在圓括號中,用逗號分隔
- 表達式主體可以是零條或多條語句,包含在花括號中
- 表達式主體只有一條語句時,花括號可省略
- 表達式主體有一條以上語句時,表達式的返回類型與代碼塊的返回類型一致
- 表達式只有一條語句時,表達式的返回類型與該語句的返回類型一致
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
//零個 ()-> System.out.println( "no argument" ); //一個 x->x+ 1 //兩個 (x,y)->x+y //省略參數(shù)類型 View.OnClickListener oneArgument = view->Log.d(TAG, "one argument" ); //指定參數(shù)類型 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 |
lambda表達式的類型
我們都知道,Java是一種強類型語言。所有的方法參數(shù)都有類型,那么lambda表達式是一種什么類型呢?
1
2
3
4
5
6
7
8
|
View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { //... } }; button.setOnClickListener(listener); |
如上所示,以往我們是通過使用單一方法的接口來代表一個方法并且重用它。
在lambda表達式中,仍使用的和之前一樣的形式。我們叫做函數(shù)式接口(functional interface)
如我們之前button的點擊響應(yīng)事件使用的 View.OnClickListener 就是一個函數(shù)式接口。
1
2
3
4
5
6
7
8
|
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { ... public interface OnClickListener { void onClick(View v); } ... } |
那究竟什么樣的接口是函數(shù)式接口呢?
函數(shù)式接口是只有一個抽象方法的接口。用作表示lambda表達式的類型。
Java8 API中新增了許多函數(shù)式接口:
接口名 | 參數(shù) | 返回值 | 用途 |
---|---|---|---|
Predicate |
T | boolean | 斷言 |
Consumer |
T | void | 消費 |
Function | T | R | 函數(shù) |
Supplier |
None | T | 工廠方法 |
UnaryOperator |
T | T | 邏輯非 |
BinaryOperator |
(T,T) | T | 二元操作 |
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://www.cnblogs.com/JohnTsai/p/5584905.html