重学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  Iterable.map(transform: (T) -> R): List {
    return mapTo(ArrayList(collectionSizeOrDefault(10)), transform)
}

public inline fun > Iterable.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  Iterable.filter(predicate: (T) -> Boolean): List {
    return filterTo(ArrayList(), predicate)
}
public inline fun > Iterable.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  Iterable.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  Iterable.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  Iterable.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(1, "1"), D(1, "11"), D(2, "2"), D(3, "3"))
    val groupBy: Map> = listOf.groupBy {
        it.c
    }

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

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

flatMap

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

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

 

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

public interface Collection : Iterable 
public interface MutableIterable : Iterable 

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

 

惰性集合

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

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

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

末端操作

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

 

你可能感兴趣的:(Kotlin)