重学Kotlin——集合高阶函数

map

    val list = listOf(1, 2, 3, 4)
    val map = list.map {
        it * 2
    }

 源码:定义了 map 的扩展函数 mapTo ,mapTo 接受两个参数,第一个参数类型是集合,第二个参数为一个方法  (transform: (T) -> R) ,最终返回一个集合,mapTo中将 transform 方法产生的结果添加到一个新集合里面去,最终返回这个新集合。

public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
    return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}

public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapTo(destination: C, transform: (T) -> R): C {
    for (item in this)
        destination.add(transform(item))
    return destination
}

filter

    val filter = list.filter {
        it > 2
    }

与map类似,接受一个函数,该函数返回值必须是Boolean,(predicate: (T) -> Boolean)。通过遍历给定的列表,将每一个元素传入 predicate 函数中,如果返回值为 true 就保留,反之则弃之,最终返回一个满足条件的列表。

public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
    return filterTo(ArrayList<T>(), predicate)
}
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
    for (element in this) if (predicate(element)) destination.add(element)
    return destination
}

相关

filterNot:与filter相反,过滤掉满足条件的元素

filterNotNull:过滤掉值为 null 元素

count:统计满足条件的元素的个数

sum,求和

public inline fun <T> Iterable<T>.sumBy(selector: (T) -> Int): Int {
    var sum: Int = 0
    for (element in this) {
        sum += selector(element)
    }
    return sum
}

fold

    val fold = list.fold(0) { i, t ->
        i * t
    }

第一个参数 initial 为初始值,第二个参数 operation 是一个函数。在实现的时候,通过 for 语句来遍历集合中每个元素,每次都调用 operation 函数,而该函数的参数有两个,一个是上次调用该函数的结果,另外一个则是当前遍历到的集合元素。

public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R {
    var accumulator = initial
    for (element in this) accumulator = operation(accumulator, element)
    return accumulator
}

fold 很好地利用了递归的思想

reduce

reduce 与 fold 相似,但没有初始默认值,初始值是集合中第一个元素 

public inline fun <S, T : S> Iterable<T>.reduce(operation: (acc: S, T) -> S): S {
    val iterator = this.iterator()
    if (!iterator.hasNext()) throw UnsupportedOperationException("Empty collection can't be reduced.")
    var accumulator: S = iterator.next()
    while (iterator.hasNext()) {
        accumulator = operation(accumulator, iterator.next())
    }
    return accumulator
}

groupBy 

    val listOf = listOf<D>(D(1, "1"), D(1, "11"), D(2, "2"), D(3, "3"))
    val groupBy: Map<Int, List<D>> = listOf.groupBy {
        it.c
    }

将 list 按照 传入的 keySelector 进行分组

public inline fun <T, K> Iterable<T>.groupBy(keySelector: (T) -> K): Map<K, List<T>> {
    return groupByTo(LinkedHashMap<K, MutableList<T>>(), keySelector)
}
public inline fun <T, K, M : MutableMap<in K, MutableList<T>>> Iterable<T>.groupByTo(destination: M, keySelector: (T) -> K): M {
    for (element in this) {
        val key = keySelector(element)
        val list = destination.getOrPut(key) { ArrayList<T>() }
        list.add(element)
    }
    return destination
}

flatMap

flatMap 接受一个参数 transform ,调用 flatMapTo 。flatMapTo 遍历集合中的元素,将每个元素传入函数 transform 中得到一个列表,然后将这个列表中的所有元素添加到空列表 destination 中,并返回。

public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> {
    return flatMapTo(ArrayList<R>(), transform)
}
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.flatMapTo(destination: C, transform: (T) -> Iterable<R>): C {
    for (element in this) {
        val list = transform(element)
        destination.addAll(list)
    }
    return destination
}

 

Iterable 为 Kotlin 集合库地顶层接口,集合分为两种,一种是 Mutable 前缀地,一种是不带地。MutableCollection 可变

public interface Collection<out E> : Iterable<E> 
public interface MutableIterable<out T> : Iterable<T> 

Kotlin的集合都是以Java的集合库为基础来构建的,只是Kotlin通过扩展函数增强了它。

 

惰性集合

序列,通过asSequence 将一个列表转换为序列,然后在这个序列上进行相应的操作,最后通过toList 方法将序列转换为列表,解决多次集合操作产生的临时集合问题。

list.asSequence().filter { it > 2 }.map { it * 2 }.toList()

public fun <T> Iterable<T>.asSequence(): Sequence<T> {
    return Sequence { this.iterator() }
}

末端操作

末端操作就是只返回结果的操作,它的返回值不能是序列,必须是一个明确的结果。末端操作一本都放在链式操作的末尾,在执行末端操作的时候,会触发中间操作的延迟计算。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值