Kotlin collection operators

set operator

  • Set operator one (initial letters a - f)

This article introduces Kotlinthe operators in the collection, Kotlinthe version used in this article is 1.8.10

all

Determine whether all elements in the collection meet the requirements, and the return value isBoolean

For example, we need to determine whether the length of the string is greater than 4

val songs = listOf("一路向北", "搁浅", "最长的电影")
songs.all {
    
     it.length >= 4 } // false

源码实现

// 继承Collection并且为空集合,直接返回为true
// 假如有一个元素不满足条件,直接返回false
public inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean {
    
    
    if (this is Collection && isEmpty()) return true
    for (element in this) if (!predicate(element)) return false
    return true
}

any

Determine whether there is an element that satisfies the condition in the collection, and the return value isBoolean

For example, we need to judge whether there is a little brother with 185cm or more 8-pack abs

val heights = listOf(188, 165, 175)
heights.any {
    
     it >= 185 } // true

源码实现

// 继承Collection并且为空集合,直接返回为false
// 假如有一个元素满足条件,直接返回true
public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean {
    
    
    if (this is Collection && isEmpty()) return false
    for (element in this) if (predicate(element)) return true
    return false
}

contains

Whether the set contains an element, returned asBoolean

For example, to determine whether there is a child named Cai Xukun in the class

val nickname = listOf("蔡徐坤", "坤蔡徐", "蔡坤徐", "蔡徐坤")
println(nickname.contains("蔡徐坤"))  // true

源码实现

// 继承Collection,则通过Collection.contains()判断是否包含
// 负责通过indexOf判断
public operator fun <@kotlin.internal.OnlyInputTypes T> Iterable<T>.contains(element: T): Boolean {
    
    
    if (this is Collection)
        return contains(element)
    return indexOf(element) >= 0
}

count

Returns the length in the collection

val nickname = listOf("蔡徐坤", "坤蔡徐", "蔡坤徐", "蔡徐坤")
println(nickname.count()) // 4

源码实现

// 继承Collection,返回size
// 使用for循环计数
public fun <T> Iterable<T>.count(): Int {
    
    
    if (this is Collection) return size
    var count = 0
    for (element in this) checkCountOverflow(++count)
    return count
}

Returns the length of all elements in the collection that meet the condition according to the condition

For example, we need to count the number of children in the class whose height reaches 185cm

val height = listOf(188, 165, 175, 185)
println(height.count {
    
     it >= 185 } ) // 2

源码实现

// 集合并且长度为0,返回0
// 满足predicate,计数累加并返回
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
}

distinct

Filter out the same elements in the collection and return a new collection, actually by HashSetensuring that the elements are not repeated

For example, filter out students with the same name

val nickname = listOf("蔡徐坤", "坤蔡徐", "蔡坤徐", "蔡徐坤")
nickname.distinct()  // [蔡徐坤, 坤蔡徐, 蔡坤徐]

源码实现

public fun <T> Iterable<T>.distinct(): List<T> {
    
    
    return this.toMutableSet().toList()
}

distinctBy

Filter out the elements in the collection according to the conditions and return a new collection, actually by HashSetensuring that the elements are not repeated

For example filter by name length

val nickname = listOf("蔡徐坤", "蔡", "坤蔡徐", "蔡坤徐", "蔡徐")
nickname.distinctBy {
    
     it.length } // [蔡徐坤, 蔡, 蔡徐]

If you want to distinctfilter the same elements, you can write it like this (it is better to use distinctit directly)

nickname.distinctBy {
    
     it }

源码实现

// HashSet可以添加元素,就将元素添加到list
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
}

drop

Filter the first nelements in the collection and return the new collection. n < 0throws IllegalArgumentExceptionan exception, n = 0returns the original collection, n >= 集合长度returns an empty collection

val heroName = listOf("蛮三刀", "托儿索", "儿童劫", "提款姬", "菊花信")
println(heroName.drop(0)) // [蛮三刀, 托儿索, 儿童劫, 提款姬, 菊花信]
println(heroName.drop(2)) // [儿童劫, 提款姬, 菊花信]
println(heroName.drop(6)) // []

源码实现

// n = 0,返回toList()
// 继承Collection时,获取去除后的集合长度,长度为0返回emptyList,长度为1返回最后一个元素,否则通过ArrayList添加元素
public fun <T> Iterable<T>.drop(n: Int): List<T> {
    
    
    require(n >= 0) {
    
     "Requested element count $n is less than zero." }
    if (n == 0) return toList()
    val list: ArrayList<T>
    if (this is Collection<*>) {
    
    
        val resultSize = size - n
        if (resultSize <= 0)
            return emptyList()
        if (resultSize == 1)
            return listOf(last())
        list = ArrayList<T>(resultSize)
        if (this is List<T>) {
    
    
            if (this is RandomAccess) {
    
    
                for (index in n until size)
                    list.add(this[index])
            } else {
    
    
                for (item in listIterator(n))
                    list.add(item)
            }
            return list
        }
    }
    else {
    
    
        list = ArrayList<T>()
    }
    var count = 0
    for (item in this) {
    
    
        if (count >= n) list.add(item) else ++count
    }
    return list.optimizeReadOnlyList()
}

dropLast

Just dropthe opposite of dropLastis to filter from the tail. n < 0throws IllegalArgumentExceptionan exception, n = 0returns the original collection, n >= 集合长度returns an empty collection

val heroName = listOf("蛮三刀", "托儿索", "儿童劫", "提款姬", "菊花信")
println(heroName.dropLast(0))  // [蛮三刀, 托儿索, 儿童劫, 提款姬, 菊花信]
println(heroName.dropLast(2))  // [蛮三刀, 托儿索, 儿童劫]
println(heroName.dropLast(6))  // []

源码实现

// 通过take()获取结果,take后面再说
public fun <T> List<T>.dropLast(n: Int): List<T> {
    
    
    require(n >= 0) {
    
     "Requested element count $n is less than zero." }
    return take((size - n).coerceAtLeast(0))
}

dropLastWhile

Filter elements from the end according to the condition, and return when an element does not meet the condition

For example, there are too many job seekers now, the company needs to adhere to the principle of first come, first served and the position is more suitable for tall people, and discard the job seekers at the end

val heights = listOf(185, 158, 177, 190, 169, 170, 168)
println(heights.dropLastWhile {
    
     it <= 175 }) // [185, 158, 177, 190]
println(heights.dropLastWhile {
    
     it < 170 })  // [185, 158, 177, 190, 169, 170]

源码实现

// 通过迭代器从后到前迭代,直到不满足条件时通过take截取
public inline fun <T> List<T>.dropLastWhile(predicate: (T) -> Boolean): List<T> {
    
    
    if (!isEmpty()) {
    
    
        val iterator = listIterator(size)
        while (iterator.hasPrevious()) {
    
    
            if (!predicate(iterator.previous())) {
    
    
                return take(iterator.nextIndex() + 1)
            }
        }
    }
    return emptyList()
}

dropWhile

Filter elements from the head according to the condition, just dropLastWhilethe opposite, return the remaining collection until an element does not meet the condition

Still the above example, but let’s adjust the screening rules, the company needs the principle of first come first and men (or women) first, discarding the top job seekers

val names = listOf("陈女士", "张先生", "王先生", "蔡女士", "李先生", "钟女士", "朱先生")
println(names.dropWhile {
    
     it.endsWith("女士") }) // [张先生, 王先生, 蔡女士, 李先生, 钟女士, 朱先生]
println(names.dropWhile {
    
     it.endsWith("先生") }) // [陈女士, 张先生, 王先生, 蔡女士, 李先生, 钟女士, 朱先生]

源码实现

// for循环遍历,如果某个元素不满足条件,就把这个元素添加到集合并且把yielding置为true,后续的元素全部添加到集合
public inline fun <T> Iterable<T>.dropWhile(predicate: (T) -> Boolean): List<T> {
    
    
    var yielding = false
    val list = ArrayList<T>()
    for (item in this)
        if (yielding)
            list.add(item)
        else if (!predicate(item)) {
    
    
            list.add(item)
            yielding = true
        }
    return list
}

elementAt

Returns the element under the index. When the index is not in the valid range [0, lastIndex], an array out-of-bounds exception is thrown. You can use elementAtOrNullor elementAtOrElseinstead

val mobileGames = listOf("和平精英", "英雄联盟手游", "欢乐斗地主")
println(mobileGames.elementAt(1)) // 英雄联盟手游
println(mobileGames.elementAt(mobileGames.lastIndex + 1)) // java.lang.ArrayIndexOutOfBoundsException 异常

源码实现

// List通过get方法获取
// 否则通过elementAtOrElse
public fun <T> Iterable<T>.elementAt(index: Int): T {
    
    
    if (this is List)
        return get(index)
    return elementAtOrElse(index) {
    
     throw IndexOutOfBoundsException("Collection doesn't contain element at index $index.") }
}

elementAtOrElse

Returns the element under the index, and returns the default value when the index is not in the valid range [0, lastIndex]

val mobileGames = listOf("和平精英", "英雄联盟手游", "欢乐斗地主")
println(mobileGames.elementAtOrElse(1) {
    
     "未找到游戏" }) // 英雄联盟手游
println(mobileGames.elementAtOrElse(mobileGames.lastIndex + 1) {
    
     "未找到游戏" }) // 未找到游戏

源码实现

public fun <T> Iterable<T>.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T {
    
    
    if (this is List)
        return this.getOrElse(index, defaultValue)
    if (index < 0)
        return defaultValue(index)
    val iterator = iterator()
    var count = 0
    while (iterator.hasNext()) {
    
    
        val element = iterator.next()
        if (index == count++)
            return element
    }
    return defaultValue(index)
}

elementAtOrNull

Returns the element under the index, or null when the index is not in the valid range [0, lastIndex]

For example

val list = listOf(1, 2, 3, 4, 5)
list.elementAtOrNull(3) = 4
list.elementAtOrNull(5) = null

源码实现

public fun <T> Iterable<T>.elementAtOrNull(index: Int): T? {
    
    
    if (this is List)
        return this.getOrNull(index)
    if (index < 0)
        return null
    val iterator = iterator()
    var count = 0
    while (iterator.hasNext()) {
    
    
        val element = iterator.next()
        if (index == count++)
            return element
    }
    return null
}

filter

Filter elements by condition, returning all elements that meet the condition

For example

val names = listOf("司马懿", "诸葛亮", "吕布", "黄忠", "赵云", "凤雏庞统")
println(names.filter {
    
     it.length >= 3 })

源码实现

// 通过filterTo实现,filterTo后面再说
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
    
    
    return filterTo(ArrayList<T>(), predicate)
}

filterIndexed

Filter elements by condition, the filterdifference is filterIndexedthat the parameter of the function type will have an index intof typeindex

For example, we divide the collection by single and double

val names = listOf("司马懿", "诸葛亮", "吕布", "黄忠", "赵云", "凤雏庞统")
val even = names.filterIndexed {
    
     index, _ -> index % 2 == 0 } // [司马懿, 吕布, 赵云] 
val odd =  names.filterIndexed {
    
     index, _ -> index % 2 == 1 } // [诸葛亮, 黄忠, 凤雏庞统]

源码实现

// 通过filterIndexedTo实现,传进去的集合是ArrayList
public inline fun <T> Iterable<T>.filterIndexed(predicate: (index: Int, T) -> Boolean): List<T> {
    
    
    return filterIndexedTo(ArrayList<T>(), predicate)
}

filterIndexedTo

Filter elements by condition and add the filtered elements to the collection

val names = listOf("司马懿", "诸葛亮", "司马懿", "吕布", "黄忠", "赵云", "凤雏庞统")
val evenSet = hashSetOf<String>()
val oddSet = hashSetOf<String>()
val even = names.filterIndexedTo(evenSet) {
    
     index, _ -> index % 2 == 0 } // [司马懿, 凤雏庞统, 黄忠] 
val odd =  names.filterIndexedTo(oddSet) {
    
     index, _ -> index % 2 == 1 } // [吕布, 诸葛亮, 赵云]

源码实现

// 传进来的集合必须是MutableCollection,因为会通过这个集合去添加过滤后的元素,返回传进来的集合
// 通过forEachIndexed过滤满足条件的元素
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean): C {
    
    
    forEachIndexed {
    
     index, element ->
        if (predicate(index, element)) destination.add(element)
    }
    return destination
}

filterIsInstance

Filter elements of the same type and return a new collection

For example, we have the following collection, we need to divide by StringandInt

val typeValues =  listOf("蔡徐坤", 88, "唱跳rap", "篮球", 177, 68)
println(typeValues.filterIsInstance<String>()) // [蔡徐坤, 唱跳rap, 篮球]
println(typeValues.filterIsInstance<Int>()) // [88, 177, 68]

源码实现

// 通过filterIsInstanceTo实现,参数是ArrayList
public inline fun <reified R> Iterable<*>.filterIsInstance(): List<@kotlin.internal.NoInfer R> {
    
    
    return filterIsInstanceTo(ArrayList<R>())
}

filterIsInstanceTo

Filter elements of the same type and add the filtered elements to the collection

val stringSet = hashSetOf<String>()
val intSets = hashSetOf<Int>()
val typeValues = listOf("蔡徐坤", 88, "唱跳rap", "篮球", 177, 68)
println(typeValues.filterIsInstanceTo(stringSet))
println(typeValues.filterIsInstanceTo(intSets))

源码实现

// 通过for循环遍历集合,将符合类型的元素添加到传进来的集合中
public inline fun <reified R, C : MutableCollection<in R>> Iterable<*>.filterIsInstanceTo(destination: C): C {
    
    
    for (element in this) if (element is R) destination.add(element)
    return destination
}

filterNot

Filter elements by condition and return all elements that do not meet the condition, just the filteropposite

For example, we need to get the university whose name length is not equal to 4

val universitySet =
    setOf("厦门大学", "四川大学", "清华大学", "中山大学", "武汉理工大学", "华南理工大学", "中国传媒大学")
println(universitySet.filterNot {
    
     it.length == 4 }) // [武汉理工大学, 华南理工大学, 中国传媒大学]

源码实现

// 通过filterNotTo过滤
public inline fun <T> Iterable<T>.filterNot(predicate: (T) -> Boolean): List<T> {
    
    
    return filterNotTo(ArrayList<T>(), predicate)
}

filterNotNull

filter out nullelements of

val random = listOf<Any?>("蔡徐坤", 2.5f, "唱跳rap", null)
println(random.filterNotNull()) //[蔡徐坤, 2.5, 唱跳rap]

源码实现

// 通过filterNotNullTo过滤
public fun <T : Any> Iterable<T?>.filterNotNull(): List<T> {
    
    
    return filterNotNullTo(ArrayList<T>())
}

filterNotNullTo

Filter out nullthe elements of and add the remaining elements to the incoming collection

val random = listOf<Any?>("蔡徐坤", 2.5f, "唱跳rap", null)
val hashSet = hashSetOf<Any>() 
println(random.filterNotNullTo(hashSet)) // [2.5, 唱跳rap, 蔡徐坤]

源码实现

// 如果元素为空,则添加到传进来的集合中
public fun <C : MutableCollection<in T>, T : Any> Iterable<T?>.filterNotNullTo(destination: C): C {
    
    
    for (element in this) if (element != null) destination.add(element)
    return destination
}

filterNotTo

Filter elements by condition, and add elements that do not meet the condition to the incoming collection

For example

val universitySet =
    setOf("厦门大学", "四川大学", "清华大学", "中山大学", "武汉理工大学", "华南理工大学", "中国传媒大学")
val lenNot4Items = hashSetOf<String>()
println(universitySet.filterNotTo(lenNot4Items) {
    
     it.length == 4 }) // [武汉理工大学, 华南理工大学, 中国传媒大学]

源码实现

// 将不满足条件的元素添加到传进来的集合中
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterNotTo(destination: C, predicate: (T) -> Boolean): C {
    
    
    for (element in this) if (!predicate(element)) destination.add(element)
    return destination
}

filterTo

Filter elements by condition, and add elements that satisfy the condition to the incoming collection, just the filterNotToopposite of

For example

@Test
fun filterToExample() {
    
    
    val universitySet =
        setOf("厦门大学", "四川大学", "清华大学", "中山大学", "武汉理工大学", "华南理工大学", "中国传媒大学")
    val len4Items = hashSetOf<String>()
    println(universitySet.filterTo(len4Items) {
    
     it.length == 4 }) // [厦门大学, 四川大学, 中山大学, 清华大学]
}

源码实现

// for循环遍历,将满足条件的添加到集合
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
}

find

Find the first element that satisfies the condition according to the condition, if found, return directly, if not found, return null

For example

val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
println(company.find {
    
     it.startsWith("A") }) // Apple
println(company.find {
    
     it.endsWith("G") }) // null

源码实现

// 内部通过firstOrNull实现
public inline fun <T> Iterable<T>.find(predicate: (T) -> Boolean): T? {
    
    
    return firstOrNull(predicate)
}

findLast

Find the last element that satisfies the condition according to the condition. If it is found, it will return directly. If it cannot find it, it will return null, which is findopposite to the search order

For example

val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
println(company.findLast {
    
     it.startsWith("A") }) // Alibaba
println(company.findLast {
    
     it.endsWith("G") }) // null

源码实现

// 内部通过lastOrNull实现
public inline fun <T> List<T>.findLast(predicate: (T) -> Boolean): T? {
    
    
    return lastOrNull(predicate)
}

first

Return the first element or the first element that satisfies the condition. If the element is not found, NoSuchElementExceptionan exception will be thrown. You can use firstOrNullinstead

For example

val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
println(company.first()) // Google
println(company.first {
    
     it.startsWith("A") }) // Apple
println(company.first {
    
     it.endsWith("G") }) // java.util.NoSuchElementException: Collection contains no element matching the predicate.

源码实现

public fun <T> List<T>.first(): T {
    
    
    if (isEmpty())
        throw NoSuchElementException("List is empty.")
    return this[0]
}

// List 返回首个元素
// 否则使用迭代器返回
public fun <T> Iterable<T>.first(): T {
    
    
    when (this) {
    
    
        is List -> return this.first()
        else -> {
    
    
            val iterator = iterator()
            if (!iterator.hasNext())
                throw NoSuchElementException("Collection is empty.")
            return iterator.next()
        }
    }
}

firstNotNullOf

Returns the first converted non-null element, or throws NoSuchElementExceptionan exception if there is none

For example

val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
val companyMap = hashMapOf("抖音" to "字节", "快手" to "快手集团", "企鹅" to "腾讯")
println(company.firstNotNullOf {
    
     it.length }) // 6
println(company.firstNotNullOf {
    
     companyMap[it] }) // java.util.NoSuchElementException: No element of the collection was transformed to a non-null value.

源码实现

// 将转换函数传递给firstNotNullOfOrNull,如果firstNotNullOfOrNull返回空则抛出异常
public inline fun <T, R : Any> Iterable<T>.firstNotNullOf(transform: (T) -> R?): R {
    
    
    return firstNotNullOfOrNull(transform) ?: throw NoSuchElementException("No element of the collection was transformed to a non-null value.")
}

firstNotNullOfOrNull

Returns the first converted non-null element, or nonenull

For example

val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
val companyMap = hashMapOf("抖音" to "字节", "快手" to "快手集团", "企鹅" to "腾讯")
println(company.firstNotNullOfOrNull {
    
     it.length }) // 6
println(company.firstNotNullOfOrNull {
    
     companyMap[it] }) // null

源码实现

// 获取转换之后的值,如果不是空就返回
public inline fun <T, R : Any> Iterable<T>.firstNotNullOfOrNull(transform: (T) -> R?): R? {
    
    
    for (element in this) {
    
    
        val result = transform(element)
        if (result != null) {
    
    
            return result
        }
    }
    return null
}

firstOrNull

Return the first element or the first element that satisfies the condition, if not returnnull

For example

val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
println(company.firstOrNull()) // Google
println(company.firstOrNull {
    
     it.startsWith("A") }) // Apple
println(company.firstOrNull {
    
     it.endsWith("G") }) // null

源码实现

// 对list单独处理,其他都是通过迭代器处理
public fun <T> Iterable<T>.firstOrNull(): T? {
    
    
    when (this) {
    
    
        is List -> {
    
    
            if (isEmpty())
                return null
            else
                return this[0]
        }
        else -> {
    
    
            val iterator = iterator()
            if (!iterator.hasNext())
                return null
            return iterator.next()
        }
    }
}

// for循环遍历
public inline fun <T> Iterable<T>.firstOrNull(predicate: (T) -> Boolean): T? {
    
    
    for (element in this) if (predicate(element)) return element
    return null
}

flatMap

The elements in the set get new values ​​according to the conversion function, and all the values ​​are flattened into the new set. Different mapfrom , flatMapthe conversion function needs to return a new collection, and will flatten the converted values ​​into the collection, so if there are nested collections converted into single-layer collections, please useflatMap

For example

val intList = listOf(1, 2, 3, 4, 5)
val nestList = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6, 7))
println(intList.flatMap {
    
     listOf(it + it, it * it, it * it * it) }) // [2, 1, 1, 4, 4, 8, 6, 9, 27, 8, 16, 64, 10, 25, 125]
println(nestList.flatMap {
    
     item -> item.map {
    
     it * it } }) // [1, 4, 9, 16, 25, 36, 49]

源码实现

// flatMapTo到ArrayList
public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> {
    
    
    return flatMapTo(ArrayList<R>(), transform)
}

flatMapIndexed

Same flatMapas , but lambdawith an extra indexindex parameter

For example

val intList = listOf(1, 2, 3, 4, 5)
println(intList.flatMapIndexed {
    
     index, it -> listOf(it + it, it * it, it * it * it) })

源码实现

// flatMapIndexedTo到ArrayList
public inline fun <T, R> Iterable<T>.flatMapIndexed(transform: (index: Int, T) -> Iterable<R>): List<R> {
    
    
    return flatMapIndexedTo(ArrayList<R>(), transform)
}

flatMapIndexedTo

flatMapIndexedThe source code of the final implementation, adding the converted elements to the incoming collection

For example

val intList = listOf(1, 2, 3, 4, 5)
val hashSet = hashSetOf<Int>()
println(intList.flatMapIndexedTo(hashSet) {
    
     index, it -> listOf(it + it, it * it, it * it * it) }) // [16, 64, 1, 2, 4, 6, 8, 9, 25, 10, 27, 125]
println(hashSet) // [16, 64, 1, 2, 4, 6, 8, 9, 25, 10, 27, 125]

源码实现

// 遍历整个集合,将转换函数获得的集合添加到传进来的集合中
// checkIndexOverflow是防止数组越界
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.flatMapIndexedTo(destination: C, transform: (index: Int, T) -> Iterable<R>): C {
    
    
    var index = 0
    for (element in this) {
    
    
        val list = transform(checkIndexOverflow(index++), element)
        destination.addAll(list)
    }
    return destination
}

flatMapTo

flatMapThe source code of the final implementation, adding the converted elements to the incoming collection

val nestList = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6, 7))
val destSet = hashSetOf<Int>()
println(nestList.flatMapTo(destSet) {
    
     item -> item.map {
    
     it * it } })
println(destSet)

源码实现

// 遍历整个集合,将转换函数获得的集合添加到传进来的集合中
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
}

fold

Operates on each element, returning the accumulated total value. Returns the initial value if the set is empty

For example, you need to calculate the sum or sum of squares from 1 to 5

val intList = listOf(1, 2, 3, 4, 5)
println(intList.fold(0) {
    
     prev, item -> prev + item  }) // 15
println(intList.fold(0) {
    
     prev, item -> prev + item * item  }) // 55

源码实现

// 遍历整个集合,将上一个的结果传到下一个的遍历中,需要传入初始值
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
}

foldIndexed

Same foldas but with lambdaan extra indexindex parameter in

val intList = listOf(1, 2, 3, 4, 5)
println(intList.foldIndexed(0) {
    
     index, prev, item -> prev + item })
println(intList.foldIndexed(0) {
    
     index, prev, item -> prev + item * item })

源码实现

// 遍历整个集合,将上一个的结果传到下一个的遍历中,需要传入初始值
public inline fun <T, R> Iterable<T>.foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): R {
    
    
    var index = 0
    var accumulator = initial
    for (element in this) accumulator = operation(checkIndexOverflow(index++), accumulator, element)
    return accumulator
}

foldRight

Operates on each element, returning the accumulated total value. The difference with foldis foldRightthat it accumulates from right to left and foldfrom left to right. Because it is sequential, it only works onlist

val intList = listOf(1, 2, 3, 4, 5)
println(intList.foldRight(0) {
    
     prev, item -> prev + item }) // 15

源码实现

// 通过listIterator迭代整个list,如果为空返回默认值
public inline fun <T, R> *List*<T>.foldRight(initial: R, operation: (T, acc: R) -> R): R {
    
    
    var accumulator = initial
    if (!isEmpty()) {
    
    
        val iterator = listIterator(size)
        while (iterator.hasPrevious()) {
    
    
            accumulator = operation(iterator.previous(), accumulator)
        }
    }
    return accumulator
}

foldRightIndexed

Same foldRightas but with lambdaan extra indexindex parameter in

val intList = listOf(1, 2, 3, 4, 5)
println(intList.foldIndexed(0) {
    
     index, prev, item -> prev + item })

源码实现

// // 通过listIterator迭代整个list,如果为空返回默认值
public inline fun <T, R> *List*<T>.foldRightIndexed(initial: R, operation: (index: Int, T, acc: R) -> R): R {
    
    
    var accumulator = initial
    if (!isEmpty()) {
    
    
        val iterator = listIterator(size)
        while (iterator.hasPrevious()) {
    
    
            val index = iterator.previousIndex()
            accumulator = operation(index, iterator.previous(), accumulator)
        }
    }
    return accumulator
}

forEach

forEachtraverse, lambdareturn each element

val intList = listOf(1, 2, 3, 4, 5)
intList.forEach {
    
    
    println(it)
}
// 1 2 3 4 5

源码实现

// for循环遍历
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
    
    
    for (element in this) action(element)
}

forEachIndexed

Same forEachas but with lambdaan extra indexindex parameter in

源码实现

// for循环遍历
public inline fun <T> Iterable<T>.forEachIndexed(action: (index: Int, T) -> Unit): Unit {
    
    
    var index = 0
    for (item in this) action(checkIndexOverflow(index++), item)
}

at last

If you want to become an architect or want to break through the 20-30K salary range, then don't be limited to coding and business, but you must be able to select models, expand, and improve programming thinking. In addition, a good career plan is also very important, and the habit of learning is very important, but the most important thing is to be able to persevere. Any plan that cannot be implemented consistently is empty talk.

If you have no direction, here I would like to share with you a set of "Advanced Notes on the Eight Major Modules of Android" written by a senior architect of Ali, to help you organize the messy, scattered and fragmented knowledge systematically and efficiently. Master the various knowledge points of Android development.

img

Compared with the fragmented content we usually read, the knowledge points of this note are more systematic, easier to understand and remember, and are arranged strictly according to the knowledge system.

Welcome everyone to support with one click and three links. If you need the information in the article, you can directly scan the CSDN official certification WeChat card at the end of the article to get it for free↓↓↓

PS: There is also a ChatGPT robot in the group, which can answer your work or technical questions

Guess you like

Origin blog.csdn.net/weixin_43440181/article/details/131379631