使用高階函數

Kotlin是一門可以支援函數式程式設計的語言,裡面含有大量的高階函數。尤其是我們在處理集合裡面的資料的時候經常會使用到,接下來我們就來認識認識這些高階函數,接下來我們會使用下面的數據來示範這些高階函數

data class Dog(
    val id: String,
    val name: String,
    val age: Int,
    val breed: String,
)

val list = listOf(
    Dog("096", "小黑", 4, "台灣犬"),
    Dog("034", "小固", 3, "德國狼犬"),
    Dog("076", "白助", 6, "薩摩耶"),
    Dog("035", "威威", 2, "柴犬"),
)

forEach系列

forEach系列的函數可以輪詢集合裡面的每一個元素

list.forEach { dog ->
    println(dog)
}

list.forEachIndexed { index, dog ->
    println("index: $index, $dog")
}

map系列

map系列的函數可以轉換集合裡面的元素

list.map { it.name }
list.mapIndexed { index, dog -> index to dog.name }
list.mapNotNull { dog -> dog.takeIf { it.age > 3 } }
list.mapIndexedNotNull { index, dog -> if (index > 2) dog else null }

flatMap系列

flatMap系列的函數可以轉換集合裡面的元素變成新的集合,並把這些集合合併

list.flatMap { 0..it.age }
list.flatMapIndexed { index, dog -> index..dog.age }

filter系列

filter系列的函數可以篩選特定條件的元素

list.filter { it.age > 3 }
list.filterNot {  it.age > 3}
list.filterIsInstance<Dog>()
list.filterIndexed { index, dog -> index < 2 && dog.age > 3 }
list.filterNotNull()

檢查系列

檢查系列的函數可以檢查集合有沒有符合特定條件

// 全部符合
list.all { it.age > 1 }
// 任一符合
list.any { it.name == "小黑" }
// 沒有符合
list.none { it.id == "076" }

取得元素系列

取得元素系列的函數可以依照條件取得一個元素

list.first { it.age > 3 }
list.firstOrNull { it.age > 3 }
list.firstNotNullOf { it.age > 3 }
list.firstNotNullOfOrNull { it.age > 3 }
list.last { it.age > 3 }
list.lastOrNull { it.age > 3 }
list.find { it.age > 3 }
list.findLast { it.age > 3 }
list.single { it.age > 3 }
list.singleOrNull { it.age > 3 }

associate系列

associate系列的函數可以把集合依照條件轉換成Map

list.associate { it.id to it.name }
list.associateBy { it.id }
list.associateWith { it.breed }

sortedBy系列

sortedBy系列的函數可以依照特定的條件排序集合

list.sortedBy { it.age }
list.sortedByDescending { it.age }

dropWhile系列

dropWhile系列的函數可以丟掉一個符合條件的元素

list.dropWhile { it.age > 3 }
list.dropLastWhile { it.age > 3 }

groupBy系列

groupBy系列的函數可以把集合用特定條件分類

list.groupBy { it.age }
list.groupingBy { it.age }

Kotlin的高階函數隨著版本會持續新增,所以如果看到不認識的函數不妨試試看效果如何。程式語言會一直更新,持續學習更新知識才能不斷跟上更新的腳步

惰性集合

在Kotlin裡面有一個叫做序列(Sequence)的惰性集合,惰性集合相比我們之前學到的集合類型有著一些不同之處,我們先來比較看看他們有什麼差別

Iterable
Sequence

每一步操作都會回傳一個新的Collection

每一步會回傳新的Sequence

積極的,每一步操作都會觸發運算

惰性的,有終端操作才會觸發運算

中間操作

中間操作會回傳一個Sequence諸如onEach、take、map、filter等等,中間操作描述了如何操作這個集合,但是不會馬上執行操作的效果,直到出現終端操作才會執行。

終端操作

終端操作啟動所有前面的中間操作,並產生一個結果。一旦終端操作被調用,序列的元素就會被消耗,且這個特定的序列不可以再使用。但我們可以再次建立或重新開始相同的序列。

惰性集合會依次運算每一個元素,直到滿足條件為止,所以在資料量龐大或是無法確認資料範圍的時候惰性集合就是一個很好的選擇。

Last updated