安卓語言基礎之Kotlin高階函式——Lambda表示式(一)
theme: condensed-night-purple
本文正在參加「金石計劃 . 瓜分6萬現金大獎」
前言
前段時間在技術交流群裡看一群大佬在說Kotlin的高階函式,看起來花裡胡哨,對我這個以Java語言為生產工具的安卓開發十分不友好,但是為了能以後和他們一起更好的水群,我開始學習高階函式,去了解它的魅力。
我將本篇歸屬於安卓開發基礎必備系列,因為這部分知識屬於開發語言基礎知識,此外,高階函式也是很多人推崇Kotlin的魅力所在。
正篇
首先我們看看Lambda程式設計,這個程式設計方式還是我在用Java開發安卓時候用點選事件時被Warnings提醒知曉的,AS推薦將匿名函式換為Lambda方式,再後面的學習中瞭解到這是一種語法糖。
Lambda是計算機程式語言,Lambda表示式是一個匿名函式,它可以包含表示式和語句,並且可用於建立委託或表示式目錄樹型別。
語法糖(Syntactic sugar),也譯為糖衣語法,是由英國計算機科學家彼得·約翰·蘭達(Peter J. Landin)發明的一個術語,指計算機語言中新增的某種語法,這種語法對語言的功能並沒有影響,但是更方便程式設計師使用。通常來說使用語法糖能夠增加程式的可讀性,從而減少程式程式碼出錯的機會。
Warning提醒我推薦替換成Lambda表示式:
```Java
vHello.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
替換為:
Java
vHello.setOnClickListener(v -> {
}); ``` 以上是Lambda表示式的一個例子,下面我們來詳細看看這種程式設計方式:
集合的函式式API
我們通常去尋集合種元素長度最長的寫法如下Demo:
Kotlin
val list = listOf("Apple", "Banana", "Pear")
var maxLengthFruit = ""
for (fruit in list) {
if (fruit.length > maxLengthFruit.length) {
maxLengthFruit = fruit
}
}
println("max length fruit is $maxLengthFruit")
而如果我們使用集合的函式式API就非常簡潔:
Kotlin
val list = listOf("Apple", "Banana", "Pear")
val maxLengthFruit = list.maxBy { it.length }
println("max length fruit is $maxLengthFruit")
一段for迴圈直接簡化為一句,但對於不熟悉這種表達方法的就會一頭霧水,最早我接觸的時候就感覺不利於閱讀,其實學完後就感覺這種寫法還是很爽的,接下來,為了看懂這種寫法,我們先了解一下Lambda,它就是一小段可以作為引數傳遞的程式碼,通常情況下我們程式設計都是向某個函式傳參時傳入變數,但Lambda可以做到傳入一小段程式碼,而且其實這一小段的定義中未規定長短(通常不建議在Lambda表示式編寫過長的程式碼,防止影響程式碼可讀性)。
Lambda表示式的語法結構如下:
{引數名1: 引數型別, 引數名2: 引數型別 -> 函式體}
我們可以看到,最外層是大括號,然後內部首先聲明瞭引數列表,然後用“->”符號連線結尾的函式體,表示引數列表結束和函式體開始,函式體可以編寫我們想實現的邏輯程式碼(不建議過長),最後位於最後一行的程式碼會自動作為Lambda表示式的返回值。
當然這是完整的寫法,此外還有更為簡化的版本,不過首先我們需要先了解Lambda的完整表示式,方便向更深層學習。
瞭解了完整的表示式,我們來一步步看如何簡化到之前的程式碼的:
maxBy其實是一個普通的函式,它可以接受一個Lambda型別的引數,並會遍歷集合時每次遍歷的值作為引數傳遞給Lambda表示式,也就是可以根據我們傳入的條件來遍歷集合,然後找到該條件下的最大值。
知曉了maxBy函式,那麼首先,我們可以根據完整表示式寫出如下程式碼:
Kotlin
val list = listOf("Apple", "Banana", "Pear")
val lambda = { fruit: String -> fruit.length}
val maxLengthFruit = list.maxBy(lambda)
println("max length fruit is $maxLengthFruit")
我們將Lambda表示式作為引數傳入了maxBy函式中,但其實是可以去簡化該寫法的,因為我們不需要專門去定義一個lambda變數,直接將其視為引數傳入該函式中:
Kotlin
val list = listOf("Apple", "Banana", "Pear")
val maxLengthFruit = list.maxBy({ fruit: String -> fruit.length})
println("max length fruit is $maxLengthFruit")
此時,編譯器會報Warning:
這告訴我們當Lambda引數是函式的唯一一個引數時,可以將函式的括號省略:
Kotlin
val list = listOf("Apple", "Banana", "Pear")
val maxLengthFruit = list.maxBy { fruit: String -> fruit.length }
println("max length fruit is $maxLengthFruit")
由於Kotlin有型別推導機制,所以我們的Lambda表示式的引數列表在大多數情況下其實不用宣告引數型別,於是我們進一步將其簡化:
Kotlin
val maxLengthFruit = list.maxBy { fruit -> fruit.length }
而Lambda表示式在引數列表中只有一個引數時甚至不用宣告引數名,即可用it關鍵字來代替,於是最終變成我們最初看到的那個最簡程式碼:
Kotlin
val maxLengthFruit = list.maxBy { it.length }
其他常用的集合函式式API
除了maxBy函式API以外,還有好幾個很好用的集合函式式API,比如:
map函式
這個函式用於將集合的每個元素都對映成另外的值,對映規則在Lambda表示式中指定,然後生成一個新的集合,如下Demo:
Kotlin
val list = listOf("Apple", "Banana", "Pear")
val newList = list.map { it.uppercase(Locale.getDefault()) }
for (fruit in newList) {
println(fruit)
}
上述程式碼將list的元素全部變為大寫,然後生成新的列表。
filter函式
這個函式可以用來過濾集合的一些資料,可以單獨使用也能結合map函式一起使用,如下demo:
Kotlin
val newList = list.filter { it.length <= 5 }
.map { it.uppercase(Locale.getDefault()) }
上面程式碼可以將生成的新列表元素長度控制在5個字元以內。
any與all函式
any函式可以用於判斷集合中是否至少存在一個元素滿足指定條件,而all函式則用於判斷集合中是否所有元素都滿足指定條件,如下demo:
val anyResult = list.any { it.length <= 5 }
val allResult = list.all { it.length <= 5 }
println("anyResult is $anyResult, allResult is $allResult")
上面程式碼條件設定為元素長度是否在5個字元以內,allResult要所有元素滿足該條件才能true,而anyResult只要有一個元素滿足條件即返回true。
總結
本篇主要是講述了Lambda程式設計中集合的函式式API用法,是Kotlin高階函式的前置第一篇,下一篇我們看看Lambda程式設計的Java函式式API的用法,其實就是開篇說到的點選事件的那種型別,然後我們再去探究Kotlin中的高階函式如何去寫。
- 安卓開發一年技術小結——安卓開發技術整理
- 安卓Kotlin開發學習——接著看高階函式
- 兔兔按鈕——安卓懸浮按鈕
- 兔兔進度條Plus——SeekBar充當Progress
- 安卓基礎開發——ReentrantLock的簡單使用
- 安卓開發基礎——使用RecyclerView
- 安卓開發基礎(Java)——TextView的使用
- 安卓開發基礎——弱引用的使用
- 安卓開發基礎——實現音訊檔案的播放
- 讓UI忙碌的安卓Lottie動畫渲染庫(二)
- 強大而靈活的RecyclerView Adapter——BRVAH(框架引入與BaseQuickAdapter使用篇)
- 安卓語言基礎之Kotlin的面向物件程式設計
- 安卓語言基礎之Kotlin高階函式——Lambda表示式(二)
- 大放光彩的安卓Jetpack元件-ViewModel(一)
- 安卓語言基礎之Kotlin高階函式——Lambda表示式(一)
- 安卓開發必備——build.gradle檔案初探(一)
- 安卓開發學Flutter——Dart語法的一些注意點(第二篇)
- 簡單易用的安卓SharedPreferences儲存(資料儲存系列)
- 安卓開發基礎技術——WebView載入網頁
- 原汁原味的安卓檔案儲存(資料儲存系列)