高阶函数:就是把行为参数化
把筛选得行为(函数)作为参数传递到过滤器里面 代码简洁, 提高效率
对比一下
首先看一段代码,对一个集合进行遍历,有哪些方法
private fun initTest() {
val names = listOf<String>("Tom", "Apple", "Luck")
for (name in names) {
Log.i(TAG, "initTest: ${name}")
}
val log = fun(name: String) {
Log.i(TAG, "initTest: ${name}")
}
names.forEach(log)
names.forEach { name ->
Log.i(TAG, "initTest: ${name}")
}
names.forEach {
Log.i(TAG, "initTest: ${it}")
}
}
我们看 forEach源码, 可以看出方法需要一个 跟迭代器类型相同得入参,返回空得函数
@kotlin.internal.HidesMembers
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}
Kotlin 提供得一些高阶函数
举例常用到得 MaxBy MinBy Map Filter GroupBy Find Any Count等
data class Girl(val name: String, val age: Int, val addr: String)
data class BaseGirl(val name: String, val addr: String)
var Girls = listOf<Girl>(
Girl("Apple", 24, "山东"),
Girl("Luck", 14, "新疆"),
Girl("Ali", 40, "河南"),
Girl("Cuite", 40, "陕西"),
Girl("Lili", 16, "山东")
)
MaxBy/MinBy 返回产生给定函数最大(小)值的第一个元素,如果没有元素,则返回“null”。
源码看: maxBy是数组得内部方法,扩展函数,入参需要一个方法,这个方法入参泛型跟集合类型相同,返回是,泛型得某个属性
public inline fun <T, R : Comparable<R>> Iterable<T>.maxBy(selector: (T) -> R): T? {
val iterator = iterator()
if (!iterator.hasNext()) return null
var maxElem = iterator.next()
if (!iterator.hasNext()) return maxElem
var maxValue = selector(maxElem)
do {
val e = iterator.next()
val v = selector(e)
if (maxValue < v) {
maxElem = e
maxValue = v
}
} while (iterator.hasNext())
return maxElem
}
使用
var girl = Girls.maxBy {
it.age
}
println(girl)
结果
Girl(name=Ali, age=40, addr=河南)
Map 。数据转换成另一个对象。 有点像 SQL 语句里面得 Select
源码
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}
使用
var girl = Girls.map {
BaseGirl(it.name, it.addr)
}
println(girl)
结果
[BaseGirl(name=Apple, addr=山东),
BaseGirl(name=Luck, addr=新疆),
BaseGirl(name=Ali, addr=河南),
BaseGirl(name=Cuite, addr=陕西),
BaseGirl(name=Lili, addr=山东)]
Filter 条件筛选数据。 有点像SQL 里面得 where 关键字 就是查询条件
源码
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
return filterTo(ArrayList<T>(), predicate)
}
使用
var girl = Girls.filter {
it.age < 18
}
println(girl)
结果
[Girl(name=Luck, age=14, addr=新疆), Girl(name=Lili, age=16, addr=山东)]
GroupBy 分组查询返回时Map集合。 简直就是SQL 里面得 GroupBy关键字一毛一样
public inline fun <T, K> Iterable<T>.groupBy(keySelector: (T) -> K): Map<K, List<T>> {
return groupByTo(LinkedHashMap<K, MutableList<T>>(), keySelector)
}
使用
var girl = Girls.groupBy {
it.addr
}
println(girl)
结果
{山东=[Girl(name=Apple, age=24, addr=山东), Girl(name=Lili, age=16, addr=山东)],
新疆=[Girl(name=Luck, age=14, addr=新疆)],
河南=[Girl(name=Ali, age=40, addr=河南)],
陕西=[Girl(name=Cuite, age=40, addr=陕西)]}
Find/Any 查找符合条件得第一条数据/ 查找是否有符合条件得嘛返回Boolean类型
源码
public inline fun <T> Iterable<T>.find(predicate: (T) -> Boolean): T? {
return firstOrNull(predicate)
}
使用
var girl = Girls.find {
it.age == 40
}
println(girl)
结果
Girl(name=Ali, age=40, addr=河南)
Count 查找符合条件得数据条数 返回数量
源码
public inline fun <T> Iterable<T>.count(predicate: (T) -> Boolean): Int {
if (this is Collection && isEmpty()) return 0
var count = 0
for (element in this) if (predicate(element)) checkCountOverflow(++count)
return count
}
使用
var girl = Girls.count {
it.age == 40
}
println(girl)
结果
2
|