kotlin源码分析-分析和使用Collections集合

来源:互联网 发布:云计算公司怎么盈利 编辑:程序博客网 时间:2024/06/15 09:29

集合api提供了很多有用的方法,基本包含了java集合类中的所有方法,提供了更多的扩展。我们来看看有什么特别的方法,以及怎么使用,深入讲解闭包的封装和使用

/** * Returns `true` if all elements match the given [predicate]. */public inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean {    for (element in this) if (!predicate(element)) return false    return true}

这个方法是Iterable的扩展方法:列表中所有元素都满足条件就返回true,否则返回false。条件通过闭包提供,在调用的时候需要提供闭包的实现,调用如下:

var list = listOf("aa", "bb", "cc")list.all(){    ele -> ele.contains("aa")}//return false,因为其他"bb", "cc"不满足条件

闭包使用:我们注意到all方法,只有一个闭包参数,闭包参数在调用的时候,可以像上面一样,放在”()”后面,用”{}”包裹起来,这是外置闭包的方式

/** * Returns `true` if at least one element matches the given [predicate]. */public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean {    for (element in this) if (predicate(element)) return true    return false}

上面这个方法:列表中的任意一个元素满足条件,就返回true,否则返回false,调用方法参见上面

public inline fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V> {    val capacity = mapCapacity(collectionSizeOrDefault(10)).coerceAtLeast(16)    return associateTo(LinkedHashMap<K, V>(capacity), transform)}

上面这个方法:通过闭包tranform,把Iterable转换成Map

    val temp = listOf("aa", "bb", "cc")     temp.associate{         ele -> Pair(ele, ele+"_ext")     }
/** * Returns an average value of elements in the collection. */@kotlin.jvm.JvmName("averageOfByte")public fun Iterable<Byte>.average(): Double {    var sum: Double = 0.0    var count: Int = 0    for (element in this) {        sum += element        count += 1    }    return if (count == 0) Double.NaN else sum / count}

上面这个方法:计算Byte集合的平均值;API还提供了Double,long,short,float,int的计算平均值

/** * Returns the number of elements matching the given [predicate]. */public inline fun <T> Iterable<T>.count(predicate: (T) -> Boolean): Int {    var count = 0    for (element in this) if (predicate(element)) count++    return count}

上面这个方法:计算列表中满足条件的元素个数。调用方法如下:

val temp = listOf("aa", "aaa", "bb", "cc")        temp.count {             it.contains("aa")        }//return 2
/** * Returns a list containing only distinct elements from the given collection. *  * The elements in the resulting list are in the same order as they were in the source collection. */public fun <T> Iterable<T>.distinct(): List<T> {    return this.toMutableSet().toList()}

上面这个方法:Iterable转换成List,使得List都是不同的元素

也可以自定义规则去除,比如下面这个API

/** * Returns a list containing only elements from the given collection * having distinct keys returned by the given [selector] function. *  * The elements in the resulting list are in the same order as they were in the source collection. */public inline fun <T, K> Iterable<T>.distinctBy(selector: (T) -> K): List<T> {    val set = HashSet<K>()    val list = ArrayList<T>()    for (e in this) {        val key = selector(e)        if (set.add(key))            list.add(e)    }    return list}

调用如下:

var list = listOf("aa", " aa", "bb", "ccc")    var result = list.distinctBy {            it -> it.trim()    }    println(result)//输出结果是[aa, bb, ccc],因为"aa", " aa",经过trim()方法,变成一样的了,所以输出的时候去除了
/** * Returns a list containing only elements matching the given [predicate]. */public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {    return filterTo(ArrayList<T>(), predicate)}

上面这个方法:根据条件过滤列表,调用如下:

var list = listOf("aa", "bb", "cc", "dd")    var result = list.filter{ it.contains("aa") || it.contains("bb") }    println(result)    //输出结果:[aa], [bb]
/** * Returns a list containing the results of applying the given [transform] function * to each element in the original collection. */@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {    return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)}

上面这个方法:列表中的每个元素经过transform转换,并输出到List中,调用如下:

val temp = listOf("aa", "aaa", "bb", "bbb", "cc")val result = temp.map {    it -> it + ".map"}println(result)//输出结果:[aa.map, aaa.map, bb.map, bbb.map, cc.map]
/** * Returns a single list of all elements yielded from results of [transform] function being invoked on each element of original collection. */public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> {    return flatMapTo(ArrayList<R>(), transform)}

上面这个方法:Iterable的每个元素按照transform进行转换,然后全部拼凑起来。调用方法如下:

    var list = listOf("aa", "bb", "cc", "dd")    var result = list.flatMap{        it -> listOf(it + 1, it + 2, it + 3)    }    println(result)    //输出结果:[aa1, aa2, aa3, bb1, bb2, bb3, cc1, cc2, cc3, dd1, dd2, dd3]
/** * Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element. */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}

上面这个方法:根据operation展开Iterable,并把结果输出到R, 调用方法如下:

  val temp = listOf("aa", " bb", "cc", "dd")   val result = temp.fold(hashMapOf<String, String>()) {       map, it -> map.put(it+"_key", it)       map   }   println(result)   //输出结果:{dd_key=dd,  bb_key= bb, aa_key=aa, cc_key=cc},   //我们这里选用的输出类型是HashMap
/** * Groups elements of the original collection by the key returned by the given [keySelector] function * applied to each element and returns a map where each group key is associated with a list of corresponding elements. *  * The returned map preserves the entry iteration order of the keys produced from the original collection. *  * @sample samples.collections.Collections.Transformations.groupBy */public inline fun <T, K> Iterable<T>.groupBy(keySelector: (T) -> K): Map<K, List<T>> {    return groupByTo(LinkedHashMap<K, MutableList<T>>(), keySelector)}

上面这个方法:根据keySelector提供的规则,对列表进行分组,并输出到Map

val temp = listOf("aa", "aaa", "bb", "bbb", "cc") val result = temp.groupBy { it ->     when(it[0]){         'a' -> "A组"         'b' -> "B组"         'c' -> "C组"         else -> "其他分组"     } } println(result) //输出结果:{A组=[aa, aaa], B组=[bb, bbb], C组=[cc]}
/** * Returns a list of all elements sorted according to natural sort order of the value returned by specified [selector] function. */public inline fun <T, R : Comparable<R>> Iterable<T>.sortedBy(crossinline selector: (T) -> R?): List<T> {    return sortedWith(compareBy(selector))}

上面这个方法:对列表进行排序,调用如下:

val temp = listOf("aa", "cc", "dd", "bb")val result = temp.sortedBy{     it    //或者: it -> it}println(result)
/** * Returns a list of all elements sorted according to the specified [comparator]. */public fun <T> Iterable<T>.sortedWith(comparator: Comparator<in T>): List<T> {    if (this is Collection) {       if (size <= 1) return this.toList()       @Suppress("UNCHECKED_CAST")       return (toTypedArray<Any?>() as Array<T>).apply { sortWith(comparator) }.asList()    }    return toMutableList().apply { sortWith(comparator) }}

上面这个方法:对列表进行排序,调用如下:

val temp = listOf("aa", "cc", "dd", "bb")val result = temp.sortedWith(compareBy{it})println(result)//输出结果[aa, bb, cc, dd]
/** * Returns a list of values built from elements of both collections with same indexes using provided [transform]. List has length of shortest collection. */public inline fun <T, R, V> Iterable<T>.zip(other: Array<out R>, transform: (a: T, b: R) -> V): List<V> {    val arraySize = other.size    val list = ArrayList<V>(minOf(collectionSizeOrDefault(10), arraySize))    var i = 0    for (element in this) {        if (i >= arraySize) break        list.add(transform(element, other[i++]))    }    return list}

上面方法:变换Iterable到List,使用如下:

val temp = listOf("aa", "cc", "dd", "bb")val result = temp.zip(arrayOf<String>("aa.key", "cc.key", "dd.key", "bb.key", "ee.key")) {        t1, t2 -> t1 to t2}println(result)//输出结果:[(aa, aa.key), (cc, cc.key), (dd, dd.key), (bb, bb.key)]

总结

kotlin的集合API还提供了其他的方法,但是经过上面的调用练习;对lambda闭包有了一定的了解,在使用其他方法,只要看下源码是怎么写的,就能知道这个方法是做什么以及怎么调用。

更多的kotlin博客:kotlin学习之路

原创粉丝点击