[TOC]
# Lambda表達式
lambda 表達式是Java8版本的新特性,采用一種簡潔的語法定義代碼塊。Android Studio 3.0 及更高版本支持所有 Java 7 語言功能,以及部分 Java 8 語言功能(具體因平臺版本而異),需要為每個模塊單獨配置使用Java8語言的新特性。
1、圖形化配置

2、代碼配置
直接在相應模塊的build.gradle文件中進行配置:
```plain
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// Kotlin 項目按如下配置
kotlinOptions {
jvmTarget = "1.8"
}
}
```
## 定義
在Android開發中,經常需要為一個控件設置點擊事件監聽器,如下:
```java
mTvLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, "click ", Toast.LENGTH_SHORT).show();
}
});
```
上面的例子中,將一個代碼塊(onClick方法)傳遞給了一個對象(mTvLogin),并且這個代碼塊會在將來某個時間調用(點擊時調用)。
但是在Java中,并不能直接傳遞一個代碼段,因為Java是一種面向對象語言,所以必須構造一個對象,這個對象的類需要有一個方法能包含所需的代碼。在上面代碼中,實際上是構造了一個類實現了OnClickListener接口,并且new了一個對象傳遞給了mTvLogin的setOnClickListener方法,由于只需要使用一次,因此使用了匿名內部類的形式來創建對象。
上述代碼的lambda表達式寫法如下:
```java
mTvLogin.setOnClickListener((View v) -> Toast.makeText(mContext, "click ", Toast.LENGTH_SHORT).show());
```
格式為:參數,箭頭(->)以及一個表達式。關于lambda表達式的格式需要注意以下幾點:
* 如果代碼塊需要完成的計算無法放在一個表達式中,可以把代碼放在{}中,并可以包含return語句。
* 如果可以推導出一個lambda表達式的參數類型,寫的時候可以忽略其類型。`(v) -> Toast.makeText(mContext, "click ", Toast.LENGTH_SHORT).show()`
* 如果方法只有一個參數,且這個參數的類型可以推導得出,甚至可以省略小括號。`v -> Toast.makeText(mContext, "click ", Toast.LENGTH_SHORT).show()`
* 即使lambda表達式沒有參數,仍然要提供空括號,就像無參數的方法一樣。`() -> Toast.makeText(mContext, "click ", Toast.LENGTH_SHORT).show()`
* 無需指定lambda表達式的返回類型,會根據上下文推導得出。`(String first, String second) -> first.length() - second.length()`可以在需要int類型結果的上下文中使用,不需要顯式書寫return語句
## 函數式接口
對于只有一個抽象方法的接口,需要這種接口的對象時,可以不再使用匿名內部類的形式,而是提供一個lambda表達式。這種接口稱為函數式接口(functional interface)。
## 方法引用
當已經有現成的方法可以完成你想要傳遞到其他代碼的某個動作時,
```java
mTvLogin.setOnClickListener(v -> System.out.println(v));
```
可以按如下調用:
```java
mTvLogin.setOnClickListener(System.out::println);
```
表達式`System.out::println`是一個方法引用,等價于lambda表達式`v -> System.out.println(v)`。`::`操作符用于分隔方法名與對象或類名,有以下3種情況:
1、`object::instanceMethod`等價于`x -> object.instanceMethod(x)`
2、`Class:staticMethod`等價于`Class.staticMethod(x)`
3、`Class:instaceMethod`等價于`(x, y) -> x.instaceMethod(y)`
第三種情況比較特殊,第一個參數會成為方法的目標,例如,`String::compareToIgnoreCase`等同于`(x, y) -> x.compareToIgnoreCase(y)`
方法引用中可以使用this參數,`this::equals`等同于`x -> this.equals(x)`;同樣使用super參數也是合法的,`super::equals`等同于`x -> super.equals(x)`,會調用父類的equals方法。
## 變量作用域
原來使用匿名內部類時,編譯后局部內部類會有一個成員變量,是對外部局部變量的引用的拷貝,使用外部局部變量時都是通過這個引用進行的。為避免這個成員變量的值被外部類的方法修改,導致使用時得到不一樣的值,需要使用final字段讓該變量不可變。
由于lambda表達式以及方法引用,都不能單獨存在,總是會轉換為函數式接口的實例。所以這一點同樣適用于lambda表達式,lambda表達式可以捕獲外部作用域中的變量的值。
- 導讀
- Java知識
- Java基本程序設計結構
- 【基礎知識】Java基礎
- 【源碼分析】Okio
- 【源碼分析】深入理解i++和++i
- 【專題分析】JVM與GC
- 【面試清單】Java基本程序設計結構
- 對象與類
- 【基礎知識】對象與類
- 【專題分析】Java類加載過程
- 【面試清單】對象與類
- 泛型
- 【基礎知識】泛型
- 【面試清單】泛型
- 集合
- 【基礎知識】集合
- 【源碼分析】SparseArray
- 【面試清單】集合
- 多線程
- 【基礎知識】多線程
- 【源碼分析】ThreadPoolExecutor源碼分析
- 【專題分析】volatile關鍵字
- 【面試清單】多線程
- Java新特性
- 【專題分析】Lambda表達式
- 【專題分析】注解
- 【面試清單】Java新特性
- Effective Java筆記
- Android知識
- Activity
- 【基礎知識】Activity
- 【專題分析】運行時權限
- 【專題分析】使用Intent打開三方應用
- 【源碼分析】Activity的工作過程
- 【面試清單】Activity
- 架構組件
- 【專題分析】MVC、MVP與MVVM
- 【專題分析】數據綁定
- 【面試清單】架構組件
- 界面
- 【專題分析】自定義View
- 【專題分析】ImageView的ScaleType屬性
- 【專題分析】ConstraintLayout 使用
- 【專題分析】搞懂點九圖
- 【專題分析】Adapter
- 【源碼分析】LayoutInflater
- 【源碼分析】ViewStub
- 【源碼分析】View三大流程
- 【源碼分析】觸摸事件分發機制
- 【源碼分析】按鍵事件分發機制
- 【源碼分析】Android窗口機制
- 【面試清單】界面
- 動畫和過渡
- 【基礎知識】動畫和過渡
- 【面試清單】動畫和過渡
- 圖片和圖形
- 【專題分析】圖片加載
- 【面試清單】圖片和圖形
- 后臺任務
- 應用數據和文件
- 基于網絡的內容
- 多線程與多進程
- 【基礎知識】多線程與多進程
- 【源碼分析】Handler
- 【源碼分析】AsyncTask
- 【專題分析】Service
- 【源碼分析】Parcelable
- 【專題分析】Binder
- 【源碼分析】Messenger
- 【面試清單】多線程與多進程
- 應用優化
- 【專題分析】布局優化
- 【專題分析】繪制優化
- 【專題分析】內存優化
- 【專題分析】啟動優化
- 【專題分析】電池優化
- 【專題分析】包大小優化
- 【面試清單】應用優化
- Android新特性
- 【專題分析】狀態欄、ActionBar和導航欄
- 【專題分析】應用圖標、通知欄適配
- 【專題分析】Android新版本重要變更
- 【專題分析】唯一標識符的最佳做法
- 開源庫源碼分析
- 【源碼分析】BaseRecyclerViewAdapterHelper
- 【源碼分析】ButterKnife
- 【源碼分析】Dagger2
- 【源碼分析】EventBus3(一)
- 【源碼分析】EventBus3(二)
- 【源碼分析】Glide
- 【源碼分析】OkHttp
- 【源碼分析】Retrofit
- 其他知識
- Flutter
- 原生開發與跨平臺開發
- 整體歸納
- 狀態及狀態管理
- 零碎知識點
- 添加Flutter到現有應用
- Git知識
- Git命令
- .gitignore文件
- 設計模式
- 創建型模式
- 結構型模式
- 行為型模式
- RxJava
- 基礎
- Linux知識
- 環境變量
- Linux命令
- ADB命令
- 算法
- 常見數據結構及實現
- 數組
- 排序算法
- 鏈表
- 二叉樹
- 棧和隊列
- 算法時間復雜度
- 常見算法思想
- 其他技術
- 正則表達式
- 編碼格式
- HTTP與HTTPS
- 【面試清單】其他知識
- 開發歸納
- Android零碎問題
- 其他零碎問題
- 開發思路