目錄結構:
1:怎么在studio中使用lambda表達式;
2:lambda表達式的使用;
1:怎么在studio中使用lambda表達式
怎么在Android studio項目里面使用java 8的新特性功能lambda表達式呢?
google developer 官方文檔里面提供了3種方法:
方法
前提使用JAVA 8
1:使用jack工具鏈;
jack方式
配置 Gradle
要為您的項目啟用 Java 8 語言功能和 Jack匠抗,請在模塊級別的 build.gradle 文件中輸入以下內(nèi)容:
android {
...
defaultConfig {
...
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Instant Run 目前不能用于 Jack鹉梨,在使用新的工具鏈時將被停用,所以不建議使用這種方式.
2:使用 Retrolambda插件
配置Gradel
要為您的項目啟用 Java 8 語言功能和 retrolambda京革,請在模塊級別的 build.gradle 文件中輸入以下內(nèi)容:
android {
...
defaultConfig {
...
}
// Keep the following configuration in order to target Java 8.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
apply plugin: 'me.tatarka.retrolambda'
不明白的細節(jié)可以看官方文檔
buildscript {
...
dependencies {
classpath 'me.tatarka:gradle-retrolambda:<version_number>'
}
}
gradle-retrolambda版本選擇
gradle-retrolambda官方文檔
3:
前面兩種是使用插件完成,第三種,看google文檔中寫到,Android studio 3.0 preview 1之后,可以不適用工具鏈插件. 明確指出禁用jack工具鏈.
前提
To start using supported Java 8 language features, update the Android plugin to 3.0.0-alpha1
(or higher) and add the following to your module’sbuild.gradle
file:
這里的這個plugin 3.0.0-alpha1 不知道怎么搞.等回頭試過了更新此部分.
// Keep the following configuration in order to target Java 8.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
目前推薦使用gradle-retrolambda插件的這種方式.
2:lambda表達式的使用
lambda 表達式有三種形式,分別是:
a:函數(shù)式接口
b:方法引用
c:構造器引用
Lambda 表達式由參數(shù)列表叛薯、箭頭和 Lambda 主體(語句塊)組成奶是。
( 參數(shù)列表... ) -> { 語句塊... }
lambda表達式 | 含義 |
---|---|
(String s) -> s.length() | 表達式具有一個 String 類型的參數(shù)并返回一個 int复旬。 Lambda 沒有 return 語句慨飘,因為已經(jīng)隱含的 return某残,可以顯示調(diào)用 return代咸。 |
(T t) -> R | 傳入?yún)?shù)T,返回一個R類型 |
(T t) -> void | 傳入?yún)?shù)T,不返回任何內(nèi)容 |
(T1 t,T2 t2,...) -> R | 傳入多個參數(shù),返回一個R類型 |
(T1 t,T2 t2,...) -> void | 傳入多個參數(shù),不返回任何內(nèi)容 |
使用lambda表達式的前提是:一個只定義了一個抽象方法的接口,或抽象類.
函數(shù)式接口
方法引用
以 Java 的 Predicate 接口作為示例蹈丸,此接口用來實現(xiàn)判斷功能,我們來對字符串進行全面的判空操作:
TextUtils 的 isEmpty() 方法實現(xiàn)了上述功能,所以我們可以寫作:
方法引用形式就是當邏輯實現(xiàn)只有一句且調(diào)用了已存在的方法進行處理( this 和 super 的方法也可包括在內(nèi))時逻杖,對函數(shù)式接口形式的 lambda 表達式進行進一步的簡化奋岁。傳入引用方法的參數(shù)就是原接口方法的參數(shù)。
接下來總結一下方法引用形式的三種格式:
object :: instanceMethod
直接調(diào)用任意對象的實例方法荸百,如 obj::equals 代表調(diào)用 obj 的 equals 方法與接口方法參數(shù)比較是否相等闻伶,效果等同 obj.equals(t);。
ClassName :: staticMethod
當前類的方法可用this::method進行調(diào)用够话,父類方法同理虾攻。
直接調(diào)用某類的靜態(tài)方法,并將接口方法參數(shù)傳入更鲁,如上述 TextUtils::isEmpty霎箍,效果等同 TextUtils.isEmpty(s);
ClassName :: instanceMethod
較為特殊,將接口方法參數(shù)列表的第一個參數(shù)作為方法調(diào)用者,其余參數(shù)作為方法參數(shù)澡为。由于此類接口較少漂坏,故選擇 Java 提供的 BiFunction 接口作為示例,該接口方法接收一個 T1 類對象和一個 T2 類對象媒至,通過處理后返回 R 類對象
值得注意的是方法引用圖2中的這種方式,固定第一個參數(shù)作為方法調(diào)用者,其他參數(shù)作為方法參數(shù)
構造器引用
對于一個現(xiàn)有構造函數(shù)顶别,可以利用它的名稱和關鍵字 new 來創(chuàng)建它的一個引用:ClassName::new。它的功能與指向靜態(tài)方法的引用類似拒啰。
例如驯绎,假設有一個構造函數(shù)沒有參數(shù)。 它適合 Supplier 的簽名() -> Apple谋旦∈JВ可以這樣做:
Supplier<Apple> c1 = Apple::new; //構造函數(shù)引用指向默認的 Apple() 構造函數(shù)
Apple a1 = c1.get(); //產(chǎn)生一個新的對象
//等價于:
Supplier<Apple> c1 = () -> new Apple(); //利用默認構造函數(shù)創(chuàng)建 Apple 的 Lambda 表達式
Apple a1 = c1.get();
Supplier接口
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
如果你的構造函數(shù)的簽名是Apple(Integer weight),那么它就適合 Function 接口的簽名册着,于是可以這樣寫:
Function<Integer, Apple> c2 = Apple::new; //構造函數(shù)引用指向 Apple(Integer weight) 構造函數(shù)
Apple a2 = c2.apple(100);
//等價于:
Function<Integer, Apple> c2 = (Integer weight) -> new Apple(weight);
Apple a2 = c2.apple(100);
類型檢查
Lambda 的類型是從使用 Lambda 的上下文推斷出來的拴孤。上下文(比如接受它傳遞的方法的參數(shù),或接受它的值的局部變量)中 Lambda 表達式需要的類型稱為目標類型甲捏。下圖表示了代碼的類型檢查過程:
首先演熟,找出 filter 方法的聲明;
第二司顿,找出目標類型 Predicate<Apple>芒粹。
第三,Predicate<Apple>是一個函數(shù)式接口大溜,定義了一個叫作 test 的抽象方法化漆。
第四,test 方法描述了一個函數(shù)描述符猎提,它可以接受一個 Apple获三,并返回一個 boolean旁蔼。
最后,filter 的任何實際參數(shù)都必須匹配這個要求疙教。
搬東搬西湊成了這篇筆記,時不時自己好回憶下.
參考鏈接
2:郭神公眾號