Kotlin集合函数式API解析_下

一、映射类操作符

1.1 flatMap 系列

flatMap(transform: (T) -> Iterable<R>)

  • 基本定义

    根据条件合并两个集合,组成一个新的集合

  • 源码定义与解析

    public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> {
        return flatMapTo(ArrayList<R>(), transform)
    }
    
    /**
     * Appends all elements yielded from results of [transform] function being invoked on each element of original collection, to the given [destination].
     */
    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
    }
    复制代码

    flatMap是一个扩展函数,借助flatMapTo函数实现

    通过外部传入的R泛型,创建一个R泛型的ArrayList可变集合,用于收集条件变换后的集合。flatMapTo内部是遍历集合,对集合中元素进行条件转换后加入到集合中,最后返回该集合

  • 使用示例

    flatMap操作符适用于:根据条件合并两个集合,组成一个新的集合

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.flatMap { listOf(it.plus("kotlin")) })
    }
    /******打印结果******/
    [javakotlin, javaScriptkotlin, kotlinkotlin, Ckotlin, C++kotlin, javaFxkotlin, pythonkotlin, Gokotlin, Swiftkotlin, Scalakotlin]
    复制代码

flatMapTo(destination: C, transform: (T) -> Iterable<R>)

  • 基本定义

    根据条件合并两个集合,组成一个新的集合

  • 源码定义与解析

    /**
     * Appends all elements yielded from results of [transform] function being invoked on each element of original collection, to the given [destination].
     */
    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
    }
    复制代码
  • 使用示例

    flatMapTo操作符适用于:多个集合的条件合并

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        val strList2 = listOf("11","22","33")
        val resultList = mutableListOf<String>().apply {
            strList.flatMapTo(this) {
                listOf(it.plus("kotlin"))
            }
            strList2.flatMapTo(this) {
                listOf(it.plus("kotlin"))
            }
        }
        print(resultList)
    
    }
    /******打印结果******/
    [javakotlin, javaScriptkotlin, kotlinkotlin, Ckotlin, C++kotlin, javaFxkotlin, pythonkotlin, Gokotlin, Swiftkotlin, Scalakotlin, 11kotlin, 22kotlin, 33kotlin]
    复制代码

1.2 group 系列

groupBy(keySelector: (T) -> K)

  • 基本定义

    分组操作符,接收一个或两个lambda表达式并返回一个Map

  • 源码定义与解析

    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
    }
    
    public inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
        val value = get(key)
        return if (value == null) {
            val answer = defaultValue()
            put(key, answer)
            answer
        } else {
            value
        }
    }
    复制代码

    groupBy是一个扩展函数,借助groupByTo函数实现

  • 使用示例

    groupBy操作符适用于:根据条件将集合拆分为一个map类型集合

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.groupBy { if (it.startsWith("java")) "java" else "kotlin" })
    }
    /******打印结果******/
    {java=[java, javaScript, javaFx], kotlin=[kotlin, C, C++, python, Go, Swift, Scala]}
    复制代码

groupByTo(destination: M, keySelector: (T) -> K)

  • 基本定义

    分组操作

  • 源码定义与解析

    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
    }
    复制代码
  • 使用示例

    分组操作,适用于多个集合的分组操作

    fun main(args: Array<String>) {
        val strList = listOf<String>("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        val numberList = listOf("111","222","333","444","555")
        val mutableMap = mutableMapOf<String,MutableList<String>>().apply {
            strList.groupByTo(this) {
                if (it.startsWith("java")) "java" else "not java"
            }
            numberList.groupByTo(this) {
                if (it.startsWith("222")) "222" else "not 222"
            }
        }
        print(mutableMap)
    }
    /******打印结果******/
    {java=[java, javaScript, javaFx], not java=[kotlin, C, C++, python, Go, Swift, Scala], not 222=[111, 333, 444, 555], 222=[222]}
    复制代码

groupingBy(crossinline keySelector: (T) -> K)

  • 基本定义

    对元素进行分组,然后一次将操作应用于所有分组

  • 源码定义与解析

    /**
     * Creates a [Grouping] source from a collection to be used later with one of group-and-fold operations
     * using the specified [keySelector] function to extract a key from each element.
     * 
     * @sample samples.collections.Grouping.groupingByEachCount
     */
    @SinceKotlin("1.1")
    public inline fun <T, K> Iterable<T>.groupingBy(crossinline keySelector: (T) -> K): Grouping<T, K> {
        return object : Grouping<T, K> {
            override fun sourceIterator(): Iterator<T> = this@groupingBy.iterator()
            override fun keyOf(element: T): K = keySelector(element)
        }
    }
    
    @SinceKotlin("1.1")
    public interface Grouping<T, out K> {
        /** Returns an [Iterator] over the elements of the source of this grouping. */
        fun sourceIterator(): Iterator<T>
        /** Extracts the key of an [element]. */
        fun keyOf(element: T): K
    }
    复制代码

    Grouping 支持以下操作:

    • eachCount() 计算每个组中的元素。
    • fold()reduce() 对每个组分别执行 fold 与 reduce 操作,作为一个单独的集合并返回结果。
    • aggregate() 随后将给定操作应用于每个组中的所有元素并返回结果。 这是对 Grouping 执行任何操作的通用方法。当折叠或缩小不够时,可使用它来实现自定义操作。
  • 使用示例

    groupingBy操作符适用于:对集合复杂分组的情况

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.groupingBy { it.startsWith("java") }.eachCount())
    }
    /******打印结果******/
    {true=3, false=7}
    复制代码

1.3 map 系列

map(transform: (T) -> R)

  • 基本定义

    把每个元素按照特定的方法进行转换,组成一个新的集合返回

  • 源码定义与解析

    /**
     * Returns a list containing the results of applying the given [transform] function
     * to each element in the original collection.
     * 
     * @sample samples.collections.Collections.Transformations.map
     */
    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
    }
    复制代码

    map操作符借助于mapTo操作符实现

  • 使用示例

    map操作符适用于:集合变换,遍历每个元素并执行给定表达式,最终形成新的集合

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.map{it.plus("kotlin")})
    }
    /******打印结果******/
    [javakotlin, javaScriptkotlin, kotlinkotlin, Ckotlin, C++kotlin, javaFxkotlin, pythonkotlin, Gokotlin, Swiftkotlin, Scalakotlin]
    复制代码

mapTo(destination: C, transform: (T) -> R)

  • 基本定义

    把每个元素按照特定的方法进行转换,组成一个新的集合返回

  • 源码定义与解析

    /**
     * Applies the given [transform] function to each element of the original collection
     * and appends the results to the given [destination].
     */
    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
    }
    复制代码
  • 使用示例

    mapTo操作符适用于:多个集合的元素转换

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(mutableListOf<String>().apply {
            strList.mapTo(this){
                it.plus("kotlin")
            }
        })
    }
    /******打印结果******/
    [javakotlin, javaScriptkotlin, kotlinkotlin, Ckotlin, C++kotlin, javaFxkotlin, pythonkotlin, Gokotlin, Swiftkotlin, Scalakotlin]
    复制代码

mapIndexed(transform: (index: Int, T) -> R)

mapIndexedTo(destination: C, transform: (index: Int, T) -> R)

  • 基本定义

    把每个元素按照特定的方法进行转换,只是其可以操作元素的下标(index),组成一个新的集合

  • 源码定义与解析

    public inline fun <T, R> Iterable<T>.mapIndexed(transform: (index: Int, T) -> R): List<R> {
        return mapIndexedTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
    }
    
    public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapIndexedTo(destination: C, transform: (index: Int, T) -> R): C {
        var index = 0
        for (item in this)
            destination.add(transform(checkIndexOverflow(index++), item))
        return destination
    }
    复制代码
  • 使用示例

    mapIndexed操作符适用于:带有元素索引下标的集合转换

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.mapIndexed{index, s ->  "$index$s"})
    }
    /******打印结果******/
    [0java, 1javaScript, 2kotlin, 3C, 4C++, 5javaFx, 6python, 7Go, 8Swift, 9Scala]
    复制代码

    mapIndexedTo操作符适用于:带有元素索引下标的多个集合转换

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(mutableListOf<String>().apply {
            strList.mapIndexedTo(this) { index, s ->
                "$index$s"
            }
        })
    }
    /******打印结果******/
    [0java, 1javaScript, 2kotlin, 3C, 4C++, 5javaFx, 6python, 7Go, 8Swift, 9Scala]
    复制代码

mapNotNull(transform: (T) -> R?)

mapNotNullTo(destination: C, transform: (T) -> R?)

  • 基本定义

    map{}函数的作用相同,过滤掉转换之后为null的元素

  • 源码定义与解析

    public inline fun <T, R : Any> Iterable<T>.mapNotNull(transform: (T) -> R?): List<R> {
        return mapNotNullTo(ArrayList<R>(), transform)
    }
    
    public inline fun <T, R : Any, C : MutableCollection<in R>> Iterable<T>.mapNotNullTo(destination: C, transform: (T) -> R?): C {
        forEach { element -> transform(element)?.let { destination.add(it) } }
        return destination
    }
    复制代码
  • 使用示例

    mapNotNull操作符适用场景与map类似,不过其过滤了集合转换后为null的元素

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.mapNotNull { if (it.startsWith("java")) null else it})
    }
    /******打印结果******/
    [kotlin, C, C++, python, Go, Swift, Scala]
    复制代码
  
`mapNotNullTo`操作符适用于多集合操作场景

**`mapIndexedNotNull`与`mapIndexedNotNullTo`同理**

# 二、元素类操作符

## 2.1 element 系列

**`elementAt(index: Int)`**

- **基本定义**

  获取集合中对应下标的元素

- **源码定义与解析**

  ```kotlin
  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.") }
  }
  
  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)
  }
  
  @kotlin.internal.InlineOnly
  public inline fun <T> List<T>.getOrElse(index: Int, defaultValue: (Int) -> T): T {
      return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index)
  }
复制代码
  • 使用示例

    elementAt操作符适用于:获取集合指定下标的元素

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.elementAt(3))
    }
    /******打印结果******/
    C
    复制代码

elementAtOrElse(index: Int, defaultValue: (Int) -> T)

  • 基本定义

    获取对应下标的集合元素。若下标越界,返回默认值

  • 源码定义与解析

    /**
     * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection.
     * 
     * @sample samples.collections.Collections.Elements.elementAtOrElse
     */
    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)
    }
    复制代码
  • 使用示例

    elementAtOrElse操作符适用于:获取对应下标的集合元素。若下标越界,返回默认值

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.elementAtOrElse(13){
            "defaultView"
        })
    }
    /******打印结果******/
    defaultView
    复制代码

elementAtOrNull(index: Int)

  • 基本定义

    获取对应下标的集合元素。若下标越界,返回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
    }
    复制代码
  • 使用示例

    elementAtOrNull操作符适用于:获取集合指定下标元素,越界返回null

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.elementAtOrNull(13))
    }
    /******打印结果******/
    null
    复制代码

2.2 first、last 系列

first()

  • 基本定义

    获取集合第一个元素,若集合为空集合,这会抛出NoSuchElementException异常

  • 源码定义与解析

    public fun <T> List<T>.first(): T {
        if (isEmpty())
            throw NoSuchElementException("List is empty.")
        return this[0]
    }
    
    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()
            }
        }
    }
    复制代码
  • 使用示例

    first操作符适用于:获取集合的首个元素

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.first())
    }
    /******打印结果******/
    java
    复制代码

first(predicate: (T) -> Boolean)

  • 基本定义

    获取集合中指定条件的第一个元素。若不满足条件,抛异常

  • 源码定义与解析

    public inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T {
        for (element in this) if (predicate(element)) return element
        throw NoSuchElementException("Collection contains no element matching the predicate.")
    }
    复制代码
  • 使用示例

    first{}操作符适用于:获取集合中满足条件的第一个元素

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.first { it.length == 6 })
    }
    /******打印结果******/
    kotlin
    复制代码

firstOrNull()

  • 基本定义

    获取集合第一个元素,若集合为空集合,返回null

  • 源码定义与解析

    ublic 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()
            }
        }
    }
    
    
    public fun <T> List<T>.firstOrNull(): T? {
        return if (isEmpty()) null else this[0]
    }
    复制代码
  • 使用示例

    firstOrNull操作符适用于:获取集合首个元素,空集合则返回null

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.firstOrNull())
    }
    /******打印结果******/
    java
    复制代码

备注

firstOrNull{}操作符适用于:获取集合满足条件的首个元素,若无则返回null

fun main(args: Array<String>) {
    val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
    print(strList.firstOrNull{
        it.endsWith("language")
    })
}
/******打印结果******/
null
复制代码

first等操作符对应的是last等相关操作符,即取集合最后一个元素等

2.3 find 系列

find(predicate: (T) -> Boolean)

  • 基本定义

    获取集合满足条件的首个元素,若无则返回null,其实就是firstOrNull{}

  • 源码定义与解析

    @kotlin.internal.InlineOnly
    public inline fun <T> Iterable<T>.find(predicate: (T) -> Boolean): T? {
        return firstOrNull(predicate)
    }
    复制代码
  • 使用示例

    find操作符使用场景与firstOrNull{}一致

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.find{
            it.endsWith("t")
        })
    }
    /******打印结果******/
    javaScript
    复制代码

findLast(predicate: (T) -> Boolean)

  • 基本定义

    获取集合满足条件的最后一个元素,若无则返回null,其实就是lastOrNull{}

  • 源码定义与解析

    @kotlin.internal.InlineOnly
    public inline fun <T> Iterable<T>.findLast(predicate: (T) -> Boolean): T? {
        return lastOrNull(predicate)
    }
    
    @kotlin.internal.InlineOnly
    public inline fun <T> List<T>.findLast(predicate: (T) -> Boolean): T? {
        return lastOrNull(predicate)
    }
    复制代码
  • 使用示例

    findLast操作符适用于获取集合满足条件的最后一个元素,若无则返回null

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.findLast{
            it.endsWith("t")
        })
    }
    /******打印结果******/
    Swift
    复制代码

2.4 single 系列

single()

  • 基本定义

    当集合中只有一个元素时,返回该元素,否则抛异常

  • 源码定义与解析

    public fun <T> Iterable<T>.single(): T {
        when (this) {
            is List -> return this.single()
            else -> {
                val iterator = iterator()
                if (!iterator.hasNext())
                    throw NoSuchElementException("Collection is empty.")
                val single = iterator.next()
                if (iterator.hasNext())
                    throw IllegalArgumentException("Collection has more than one element.")
                return single
            }
        }
    }
    
    public fun <T> List<T>.single(): T {
        return when (size) {
            0 -> throw NoSuchElementException("List is empty.")
            1 -> this[0]
            else -> throw IllegalArgumentException("List has more than one element.")
        }
    }
    复制代码
  • 使用示例

    single操作符适用于:判断集合是否只有一个元素

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        println(strList.single())
    }
    /******打印结果******/
    java.lang.IllegalArgumentException: List has more than one element.
    复制代码
    fun main(args: Array<String>) {
        val singleList = listOf<String>("java")
        println(singleList.single())
    }
    /******打印结果******/
    java
    复制代码

single(predicate: (T) -> Boolean)

  • 基本定义

    找到集合中满足条件的元素,若只有单个元素满足条件,则返回该元素,否则抛异常

  • 源码定义与解析

    public inline fun <T> Iterable<T>.single(predicate: (T) -> Boolean): T {
        var single: T? = null
        var found = false
        for (element in this) {
            if (predicate(element)) {
                if (found) throw IllegalArgumentException("Collection contains more than one matching element.")
                single = element
                found = true
            }
        }
        if (!found) throw NoSuchElementException("Collection contains no element matching the predicate.")
        @Suppress("UNCHECKED_CAST")
        return single as T
    }
    复制代码
  • 使用示例

    single{}操作符适用于:查找集合中只有单个满足条件的元素

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        println(strList.single{
            it.startsWith("py")
        })
    }
    /******打印结果******/
    python
    复制代码

备注

singleOrNullsingleOrNull{}操作符只是将前述的抛异常改为返回null

fun main(args: Array<String>) {
    val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
    println(strList.singleOrNull{
        it.startsWith("java")
    })
}
/******打印结果******/
null
复制代码

2.5 component 系列

component1()

component2()

。。。。。。

  • 基本定义

    用于获取元素

  • 源码定义与解析

    public inline operator fun <T> List<T>.component1(): T {
        return get(0)
    }
    
    @kotlin.internal.InlineOnly
    public inline operator fun <T> List<T>.component2(): T {
        return get(1)
    }
    //......最大为component5
    复制代码
  • 使用示例

    fun main(args: Array<String>) {
        val strList = listOf<String>("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        val numberList = listOf("111","212","332","444","555","111","666")
        print(numberList.component5())
    }
    /******打印结果******/
    555
    复制代码

2.6 indexOf 系列

indexOf(element: T)

  • 基本定义

    返回指定元素的下标,若不存在,则返回-1

  • 源码定义与解析

    public fun <@kotlin.internal.OnlyInputTypes T> Iterable<T>.indexOf(element: T): Int {
        if (this is List) return this.indexOf(element)
        var index = 0
        for (item in this) {
            checkIndexOverflow(index)
            if (element == item)
                return index
            index++
        }
        return -1
    }
    
    public fun <@kotlin.internal.OnlyInputTypes T> List<T>.indexOf(element: T): Int {
        return indexOf(element)
    }
    复制代码
  • 使用示例

    fun main(args: Array<String>) {
        val strList = listOf<String>("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.indexOf("C"))
    }
    /******打印结果******/
    3
    复制代码

indexOfFirst(predicate: (T) -> Boolean)

  • 基本定义

    返回第一个满足条件元素的下标,若不存在,则返回-1

  • 源码定义与解析

    public inline fun <T> Iterable<T>.indexOfFirst(predicate: (T) -> Boolean): Int {
        var index = 0
        for (item in this) {
            checkIndexOverflow(index)
            if (predicate(item))
                return index
            index++
        }
        return -1
    }
    复制代码
  • 使用示例

    indexOfFirst操作符适用于:获取满足条件的第一元素的下标

    fun main(args: Array<String>) {
        val strList = listOf<String>("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.indexOfFirst {
            it.startsWith("S")
        })
    }
    /******打印结果******/
    8
    复制代码
  • 备注

    indexOfLast操作符与其相反,获取满足条件的最后一个元素的下标

    fun main(args: Array<String>) {
        val strList = listOf<String>("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.indexOfLast {
            it.startsWith("S")
        })
    }
    /******打印结果******/
    9
    复制代码

三、排序类操作符

3.1 reverse 系列

reverse()

reversed()

  • 基本定义

    集合元素反转

  • 源码定义与解析

    /**
     * Reverses elements in the list in-place.
     */
    public expect fun <T> MutableList<T>.reverse(): Unit
    
    /**
     * Returns a list with elements in reversed order.
     */
    public fun <T> Iterable<T>.reversed(): List<T> {
        if (this is Collection && size <= 1) return toList()
        val list = toMutableList()
        list.reverse()
        return list
    }
    复制代码
  • 使用场景与示例

    reverse操作符适用于:反转集合元素

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        println(strList.reversed())
    }
    /******打印结果******/
    [Scala, Swift, Go, python, javaFx, C++, C, kotlin, javaScript, java]
    复制代码

3.2 sort 系列

sorted()

  • 基本定义

    对集合中的元素自然升序排序

  • 源码定义与解析

    public fun <T : Comparable<T>> Iterable<T>.sorted(): List<T> {
        if (this is Collection) {
            if (size <= 1) return this.toList()
            @Suppress("UNCHECKED_CAST")
            return (toTypedArray<Comparable<T>>() as Array<T>).apply { sort() }.asList()
        }
        return toMutableList().apply { sort() }
    }
    复制代码
  • 使用示例

    sorted操作符适用于:集合元素自然升序排序

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        println(strList.sorted())
    }
    /******打印结果******/
    [C, C++, Go, Scala, Swift, java, javaFx, javaScript, kotlin, python]
    复制代码

sortBy(crossinline selector: (T) -> R?)

  • 基本定义

    返回一个根据指定函数排序后的list

  • 源码定义与解析

    public inline fun <T, R : Comparable<R>> MutableList<T>.sortBy(crossinline selector: (T) -> R?): Unit {
        if (size > 1) sortWith(compareBy(selector))
    }
    
    expect fun <T> MutableList<T>.sortWith(comparator: Comparator<in T>): Unit
    复制代码
  • 使用场景与示例

    sortBy操作符适用于:根据指定函数排序

    fun main(args: Array<String>) {
        val mutableList = mutableListOf<String>("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        mutableList.sortBy {
            it.length
        }
        print(mutableList)
    }
    复制代码

sortedBy(crossinline selector: (T) -> R?)

  • 基本定义

    根据条件升序,即把不满足条件的放在前面,满足条件的放在后面

  • 源码定义与解析

    public inline fun <T, R : Comparable<R>> Iterable<T>.sortedBy(crossinline selector: (T) -> R?): List<T> {
        return sortedWith(compareBy(selector))
    }
    复制代码
  • 使用场景与示例

    sortedBy操作符适用于:根据条件升序,即把不满足条件的放在前面,满足条件的放在后面

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        println(strList.sortedBy {
            it.length
        })
    }
    /******打印结果******/
    [C, Go, C++, java, Swift, Scala, kotlin, javaFx, python, javaScript]
    复制代码
  • 备注

    sortedByDescending操作符与sortedBy相反,为倒序

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        println(strList.sortedBy {
            it.length
        })
    }
    /******打印结果******/
    [javaScript, kotlin, javaFx, python, Swift, Scala, java, C++, Go, C]
    复制代码

四、生成类

4.1 partition 系列

partition(predicate: (T) -> Boolean)

  • 基本定义

    判断元素是否满足条件把集合拆分为有两个Pair组成的新集合

  • 源码定义与解析

    /**
     * Splits the original collection into pair of lists,
     * where *first* list contains elements for which [predicate] yielded `true`,
     * while *second* list contains elements for which [predicate] yielded `false`.
     * 
     * @sample samples.collections.Iterables.Operations.partition
     */
    public inline fun <T> Iterable<T>.partition(predicate: (T) -> Boolean): Pair<List<T>, List<T>> {
        val first = ArrayList<T>()
        val second = ArrayList<T>()
        for (element in this) {
            if (predicate(element)) {
                first.add(element)
            } else {
                second.add(element)
            }
        }
        return Pair(first, second)
    }
    复制代码
  • 使用示例

    partition操作符适用于:需要将一个集合按条件拆分为两个pair组成的新集合

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        println(strList.partition {
            it.startsWith("java")
        })
    }
    /******打印结果******/
    ([java, javaScript, javaFx], [kotlin, C, C++, python, Go, Swift, Scala])
    复制代码

4.2 plus 系列

plus(element: T)

  • 基本定义

    合并两个集合中的元素,组成一个新的集合。也可以使用符号+

  • 源码定义与解析

    /**
     * Returns a list containing all elements of the original collection and then the given [element].
     */
    public operator fun <T> Iterable<T>.plus(element: T): List<T> {
        if (this is Collection) return this.plus(element)
        val result = ArrayList<T>()
        result.addAll(this)
        result.add(element)
        return result
    }
    
    public operator fun <T> Iterable<T>.plus(elements: Array<out T>): List<T> {
        if (this is Collection) return this.plus(elements)
        val result = ArrayList<T>()
        result.addAll(this)
        result.addAll(elements)
        return result
    }
    
    //......
    复制代码
  • 使用示例

    plus操作符适用于:集合合并

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        val numberList = listOf<String>("111","222","333","444")
        println(strList.plus(numberList))
    }
    /******打印结果******/
    [java, javaScript, kotlin, C, C++, javaFx, python, Go, Swift, Scala, 111, 222, 333, 444]
    复制代码

plusElement(element: T)

  • 基本定义

    在集合中添加一个元素

  • 源码定义与解析

    @kotlin.internal.InlineOnly
    public inline fun <T> Iterable<T>.plusElement(element: T): List<T> {
        return plus(element)
    }
    
    @kotlin.internal.InlineOnly
    public inline fun <T> Collection<T>.plusElement(element: T): List<T> {
        return plus(element)
    }
    复制代码
  • 使用场景与示例

    plusElement操作符适用于:往集合中添加元素

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.plusElement("plusElement"))
    }
    /******打印结果******/
    [java, javaScript, kotlin, C, C++, javaFx, python, Go, Swift, Scala, plusElement]
    复制代码

4.3 zip 系列

zip(other: Array<out R>)

  • 基本定义

    由两个集合按照相同的下标组成一个新集合。该新集合的类型是:List<Pair>

  • 源码定义与解析

    public infix fun <T, R> Iterable<T>.zip(other: Array<out R>): List<Pair<T, R>> {
        return zip(other) { t1, t2 -> t1 to t2 }
    }
    
    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
    }
    
    //......
    复制代码
  • 使用示例

    zip操作符适用于:两个集合的元素两两组合场景

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        val numberList = listOf("111","222","333","444","555")
        print(strList zip numberList)
    }
    /******打印结果******/
    [(java, 111), (javaScript, 222), (kotlin, 333), (C, 444), (C++, 555)]
    复制代码

zipWithNext()

zipWithNext(transform: (a: T, b: T) -> R)

  • 基本定义

    集合和相邻元素组成pairs

  • 源码定义与解析

    /**
     * Returns a list of pairs of each two adjacent elements in this collection.
     * 
     * The returned list is empty if this collection contains less than two elements.
     * 
     * @sample samples.collections.Collections.Transformations.zipWithNext
     */
    @SinceKotlin("1.2")
    public fun <T> Iterable<T>.zipWithNext(): List<Pair<T, T>> {
        return zipWithNext { a, b -> a to b }
    }
    
    @SinceKotlin("1.2")
    public inline fun <T, R> Iterable<T>.zipWithNext(transform: (a: T, b: T) -> R): List<R> {
        val iterator = iterator()
        if (!iterator.hasNext()) return emptyList()
        val result = mutableListOf<R>()
        var current = iterator.next()
        while (iterator.hasNext()) {
            val next = iterator.next()
            result.add(transform(current, next))
            current = next
        }
        return result
    }
    复制代码
  • 使用示例

    zipWithNext操作符适用于:集合中相邻元素组成pairs

    fun main(args: Array<String>) {
        val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala")
        print(strList.zipWithNext() )
    }
    /******打印结果******/
    [(java, javaScript), (javaScript, kotlin), (kotlin, C), (C, C++), (C++, javaFx), (javaFx, python), (python, Go), (Go, Swift), (Swift, Scala)]
    复制代码

猜你喜欢

转载自juejin.im/post/7073058767083945997