集合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学习之路