• 基本概念
      • 更改可变集合不需要它是以 var 定义的变量:写操作修改同一个可变集合对象,因此引用不会改变。 但是,如果尝试对 val 集合重新赋值,你将收到编译错误。
      • 只读集合类型是型变的。 这意味着,如果类 Rectangle 继承自 Shape,则可以在需要 List 的任何地方使用 List
    • 构造集合

      • 创建集合最常用的方法是[listOf<T>()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/list-of.html)、[setOf<T>()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/set-of.html)、[mutableListOf<T>()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-list-of.html)、[mutableSetOf<T>()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-set-of.html)

        1. val numberSet = setOf(1,2,3)
        2. val emptySet = mutableSetOf<String>()
      • 同样的,Map的创建也有mapOf()和mutableMapOf()这两个函数,映射的键值对作为pair对象传递

        //通常使用中缀函数to创建
        val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 4) 
        //to符号仅能创建一个短时存活的的pair对象,需要考虑性能问题时可创建Mutable的Map加apply函数
        val numbersMap = mutableMapOf<String, String>().apply {this["one"] = "1";this["two"] = "2" }
        
      • 空集合,可用emptyList(),emptySet(),emptyMap()来创建空集合,同时应指定集合包含的元素类型

        val empty = emptyList<String>()
        
      • 复制, 标准库中的集合是浅拷贝,深拷贝可用toList(),toMutableList(),toSet()等,在新的集合对元素进行操作不会影响副本 ```kotlin val sourceList = mutableListOf(1, 2, 3) val copyList = sourceList.toMutableList() val readOnlyCopyList = sourceList.toList() sourceList.add(4) println(“Copy size: ${copyList.size}”)
        //readOnlyCopyList.add(4) // 编译异常 println(“Read-only copy size: ${readOnlyCopyList.size}”)

    //这些函数还可以用于集合类型的转换 val sourceList = mutableListOf(1, 2, 3)
    val copySet = sourceList.toMutableSet()

    
       - 集合的初始化可用于限制其可变性。例如,如果构建了一个 MutableList 的 List 引用,当你试图通过此引用修改集合的时候,编译器会抛出错误
    ```kotlin
    val sourceList = mutableListOf(1, 2, 3)
    val referenceList: List<Int> = sourceList
    //referenceList.add(4)            // 编译错误
    sourceList.add(4)
    println(referenceList) // 显示 sourceList 当前状态
    
    • 也可以通过其他操作来创建集合如过滤列表,映射和关联
      //过滤列表
      val numbers = listOf("one","two","three","four")
      val longerThan3 = numbers.filter { it.length > 3 }
      //映射生成转换结果列表
      val numbers = setOf(1,2,3)
      println(numbers.map { it * 3 })
      println(numbers.mapIndexed { idx, value -> value * idx })
      //关联生成Map
      val numbers = listOf("one", "two", "three", "four")
      println(numbers.associateWith { it.length })
      
    • 迭代器

      • 迭代对每个元素操作主要有以下几个方法,然后List可以实现双向迭代通过previous( )来实现回溯。然后对于Mutable的集合可以进行remove,add和set等操作
        //通过iterator()函数调用迭代器然后在调用next()函数返回元素
        val numbers = listOf("one","two","three")
        val numbersIterator = numbers.iterator()
        while (numbersIterator.hasNext()) {
        println(numbersIterator.next())  
        }
        //for循环
        for(item in numbers) {
        println(item)
        }
        //forEach()循环
        numbers.forEach {
        println(it)
        }
        
    • 序列

      • 序列在处理多步骤集合时和Iterable不太相同,Sequence 对每个元素逐个执行所有处理步骤。 反过来,Iterable 完成整个集合的每个步骤,然后进行下一步,可避免生成中间步骤的结果,从而提高了整个集合处理链的性能,但同时序列的延迟性也会增加开销
      • 创建序列用sequenceOf()函数val numberSequence = sequenceOf("four","three","two","one")

             如果已经有了Iterable对象可以用asSequence()创建一个序列
        
        val numbers = listOf("one", "two", "three", "four")
        val numbersSequence = numbers.asSequence()
        
      • 可以用函数来构建序列

        val oddNumbers = generateSequence(1) { it + 2 } // `it` 是上一个元素
        println(oddNumbers.take(5).toList()) //此序列是无限的,最后一个元素是null时会停止创建
        
      • 也可以通过组块来生成序列,yield() 使用单个元素作为参数;yieldAll() 中可以采用 Iterable 对象、Iterable 或其他 Sequence

        val oddNumbers = sequence {
        yield(1)
        yieldAll(listOf(3, 5))
        yieldAll(generateSequence(7) { it + 2 })
        }
        
      • 序列的操作,主要有无状态操作用来独立处理每个元素例如map()或filter(),也可以处理少量元素如take()和drop();有状态序列操作需要大量状态,通常与序列中元素数量成比例,下面的示例展示了序列和Iterable的区别 ```kotlin val words = “The quick brown fox jumps over the lazy dog”.split(“ “) val lengthsList = words.filter { println(“filter: $it”); it.length > 3 } .map { println(“length: ${it.length}”); it.length } .take(4)

    println(“Lengths of first 4 words longer than 3 chars:”) println(lengthsList)

    ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21510613/1631872223122-ef23dfa8-c7ae-499c-a33f-2ae62245c394.png#clientId=u7d25b330-8e92-4&from=paste&id=u99932401&margin=%5Bobject%20Object%5D&name=image.png&originHeight=377&originWidth=990&originalType=url&ratio=1&size=44353&status=done&style=none&taskId=u7c9f9e78-9ca1-46b3-a8b7-dc77c7bb955)
    ```kotlin
    val words = "The quick brown fox jumps over the lazy dog".split(" ")
    // 将列表转换为序列
    val wordsSequence = words.asSequence()
    
    val lengthsSequence = wordsSequence.filter { println("filter: $it"); it.length > 3 }
        .map { println("length: ${it.length}"); it.length }
        .take(4)
    
    println("Lengths of first 4 words longer than 3 chars")
    // 末端操作:以列表形式获取结果。
    println(lengthsSequence.toList())
    

    image.png

    • 集合的转换

      • 映射,基本的映射函数是map(),他将给定的lambda函数应用于每个后续元素,如果需要元素索引作为参数转换,使用函数mapIndexed(),可使用mapNotNull()

        val numbers = setOf(1,2,3)
        println(numbers.map {it*3})
        println(numbers.mapIndexed {idx, value -> value * idx})
        //对于map可以选择映射键或者值
        val numbersMap = mapOf("key1" to 1, "key2" to 2)
        println(numbersMap.mapKeys{ it.key.toUpperCase() })
        println(numbersMap.mapValues{ it.value + it.key.length })
        
      • 合拢,zip()包两个list和成Pair 对象的列表,unzipping是从键值对中构建两个列表

        val colors = listOf("red", "brown", "grey")
        val animals = listOf("fox", "bear", "wolf")
        println(colors zip animals)
        val twoAnimals = listOf("fox", "bear")
        println(colors.zip(twoAnimals))
        [(red, fox), (brown, bear), (grey, wolf)]
        [(red, fox), (brown, bear)]
        
      • 关联,associateWith()创建一个Map,原始集合的元素是键;函数associateBy()根据元素的值返回键,如果元素的键相等就返回最后一个元素;最后还有associate()函数会生成临时的Pair()对象,可能会对性能有影响,下面是具体的示例 ```kotlin val numbers = listOf(“one”, “two”, “three”, “four”) println(numbers.associateWith {it.length} ) //{one=3, two=3, three=5, four=4} println(numbers.associateBy { it.first().uppercaseChar() } ) println(numbers.associateNy { keySelector = {it.first().upppercaseChar() }, valueTransform = {it.length} } ) {O=one, T=three, F=four} {O=3, T=5, F=4}

    
       -  铺平flatten()可以在一个集合上调用,该函数返回嵌套集合中的多有元素的一个List
    ```kotlin
    val numberSets = listOf(setOf(1,2,3), setOf(4,5,6))
    println(numberSets.flatten())
    
    • 集合的过滤

      • 主要有filter(),fiterIndexed(),filterNot(),

        val numbers = listOf("one", "two", "three", "four")
        val longerThan3 = numbers.fiter { it.length > 3 }
        val filteredIndex = numbers.fiterIndexed { index, s -> (index != 0)&&(s.length < 5) } 
        val filteredNot = numbers.filterNot { it.length <=3 }
        //filterIsInstance()
        val numbers = listOf(null, 1, "two", 3.0, "four")
        numbers.filterIsInstance<String>().forEach {
        println(it.toUpperCase())
        }
        
      • partion(), 返回两个list一个是匹配的match另一个是不匹配的其余元素rest

        val (match, rest) = numbers.partion {it.length > 3}
        
    • 分组

      val  = listOf("one", "two", "three", "four", "five")
      println(numbers.groupBy {it.first.uppercaseChar()})
      println(numbres.groupBy(keySelector = { it.first() }, valueTransform = {it.uppercaseChar() }))
      
    • 取部分集合

      • slice(),返回具有给定集合元素的列表;take(),drop(),takeLast(),dropLast()
        val numners = listOf("one", "two", "three", "four", "five", "six")
        println(numbers.silce(1..4 step 2))
        println(numbers.silce(setOf(3,5,0)))
        println(numbers.take(3))
        println(numbers.takeLast(3))
        println(numbers.drop(1))
        println(numbers.dropLast(5))
        
    • 取单个元素

      • elementAt(),第一个和最后一个元素:first()last(),当指定位置超出集合范围时,elementAtOrNull()
        val numbers = linkedSetOf("one", "two", "three", "four", "five")
        println(numbers.elementAt(3))
        println(numbers.first())    
        println(numbers.last())    
        println(numbers.elementAtOrNull(5))
        //按条件取
        println(numbers.first{ it.length > 3 })
        println(numbers.firstOrNull { it.length > 6 })
        println(numbers.find { it % 2 == 0 })
        
    • 排序

      • 基本的函数 sorted()sortedDescending() 返回集合的元素,这些元素按照其自然顺序升序和降序排序, ```kotlin val numbers = listOf(“one”, “two”, “three”, “four”)

    println(“Sorted ascending: ${numbers.sorted()}”) println(“Sorted descending: ${numbers.sortedDescending()}”)

    
       - 自定义顺序,可以自定义排序的规则,也可以对用户自定义类型进行排序,让这个类型继承Comparable同时实现compareTo()函数即可。
    ```kotlin
    val numbers = listOf("one", "two", "three", "four")
    val sortedNumbers = numbers.sortedBy { it.length }
    println("Sorted by length ascending: $sortedNumbers")
    //通过Comparable实现版本号对比
    class   Version(val major: Int, val minor: Int): Comparable<Version> {
       override fun compareTo(other: Version): Int {
          if(this.major == other.major)
            return this.minor - other.minor
          else 
            return this.major - other.major
       }
    }
    fun main() {    
        println(Version(1, 2) > Version(1, 3))
        println(Version(2, 0) > Version(1, 5))
    }
    //可以用sortedWith()加Comparator来实现同样的效果
    val lengthComparator = Comparator { str1: String, str2: String -> str1.length - str2.length }
    println(listOf("aaa", "bb", "c").sortedWith(lengthComparator))
    
    • 聚合操作

      • 大多数的函数和其他语言中的没有区别,如下所示

        val numbers = listOf(6,42,10,4)
        println("Count:${numbers.count()}")
        println("Max: ${numbers.maxOrNull()}")
        println("Min: ${numbers.minOrNull()}")
        println("Average: ${numbers.average()}")
        println("Sum: ${numbers.sum()}")
        
      • 也可以自定义Comparator对象来返回最大或最小元素

        val numbers = listOf(5, 42, 10, 4)
        val min3Remainder = numbers.minBy { it % 3 }
        println(min3Remainder)
        
      • 函数 reduce()fold(),它们依次将所提供的操作应用于集合元素并返回累积的结果。 操作有两个参数:先前的累积值和集合元素,fold() 接受一个初始值并将其用作第一步的累积值,而 reduce() 的第一步则将第一个和第二个元素作为第一步的操作参数

        val numbers = listOf(5, 2, 10, 4)
        val sum = numbers.reduce { sum, element -> sum + element }
        val sumDoubled = numbers.fold(0) { sum, element -> sum + element * 2 }
        
    • 集合的写操作

      • 添加单个元素用add()函数,要将参数对象的每个元素添加到列表或集合中需要用addAll()函数

        val numbers = mutableListOf(1, 2, 3, 4)
        numbers.add(5)
        //addAll()
        val numbers = mutableListOf(1, 2, 5, 6)
        numbers.addAll(arrayOf(7,8))
        numbers.addAll(2,setOf(3,4))//第一个参数index可以指定插入开始的位置
        
      • 同时也可以使用plus运算符,如下所示

        val numbers = mutableListOf("one", "two")
        numbers += "three"
        println(numbers)
        numbers += listOf("four", "five")    
        println(numbers)
        
      • 删除元素使用remove()函数, 同时用removeAll()移除所有符合条件的元素,clear()清空所有元素,相对应的从集合中移除元素也可以用minus操作符,具体如下

        val numbers = mutableListOf(1, 2, 3, 4, 3)
        numbers.remove(3)                    // 删除了第一个 `3`
        println(numbers)
        numbers.remove(5)                    // 什么都没删除
        println(numbers)
        //removeAll()
        val numbers = mutableListOf(1, 2, 3, 4)
        println(numbers)
        numbers.removeAll { it >= 3 }
        println(numbers)
        numbers.clear()
        println(numbers)
        //minus
        val numbers = mutableListOf("one", "two", "three", "three", "four")
        numbers -= "three"
        numbers -= listOf("four", "five")
        
    • List及Set的相关操作

      • list按索引取单个元素

        val numbers = listOf(1, 2, 3, 4)
        println(numbers.elementAt(index))
        println(numbers.first())
        println(numbers.last())
        println(numbers.get(0))
        println(numbers[0])
        println(numbers.getOrNull(5))             // null
        println(numbers.getOrElse(5, {it}))        // 5
        
      • 取列表的一部分用subList()

        val numbers = (0..13).toList()
        println(numbers.subList(3,6))
        
      • 查找元素的位置

        val numbers = listOf(1, 2, 3, 4, 2, 5)
        println(numbers.indexOf(2))
        println(numbers.lastIndexOf(2))
        val numbers = mutableListOf(1, 2, 3, 4)
        println(numbers.indexOfFirst { it > 2})
        println(numbers.indexOfLast { it % 2 == 1})
        
      • list的写操作 ```kotlin //添加 val numbers = mutableListOf(“one”,”five”,”six”) numbers.add(1,”two”) numbers.addAll(2, listOf(“three”, “four”)) println(numbers) //更新 val numbers = mutableListOf(“one”, “five”, “three”) numbers[1] = “two” numbers.set(2,””) println(numbers)


    val numbers = mutableListOf(1, 2, 3, 4) numbers.fill(3) println(numbers) //删除 val numbers = mutableListOf(1, 2, 3, 4, 3)
    numbers.removeAt(1) numbers.removeFirst() numbers.removeLast() println(numbers)

    
       -  set的相关操作, 并集用union(),交集用intersect(),差集用subtract()
    ```kotlin
    val numbers = setOf("one", "two", "three")
    
    println(numbers union setOf("four", "five"))
    println(setOf("four", "five") union numbers)
    
    println(numbers intersect setOf("two", "one"))
    println(numbers subtract setOf("three", "four"))
    println(numbers subtract setOf("four", "three")) // 相同的输出
    
    • Map的相关操作

      • 取键和值

        val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
        println(numbersMap.get("one"))
        println(numbersMap["one"])
        println(numbersMap.getOrDefault("four", 10))
        println(numbersMap["five"])               // null
        //numbersMap.getValue("six")      // exception!
        
      • 过滤

        val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
        val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
        println(filteredMap)
        //filter传递的是pair参数,而分别对键和值进行检查的是filterKeys(),filterValues()
        val filteredKeysMap = numbersMap.filterKeys { it.endsWith("1") }
        val filteredValuesMap = numbersMap.filterValues { it < 10 }
        
      • plus和minus操作

        val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
        println(numbersMap + Pair("four", 4))
        println(numbersMap + Pair("one", 10))
        println(numbersMap + mapOf("five" to 5, "one" to 11))
        println(numbersMap - "one")
        println(numbersMap - listOf("two", "four"))
        
      • 添加,更新条目

        val numbersMap = mutableMapOf("one" to 1, "two" to 2)
        numbersMap.put("three", 3)
        numbersMap.putAll(setOf("four" to 4, "five" to 5))
        
      • 删除条目

        val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
        numbersMap.remove("one")
        println(numbersMap)
        numbersMap.remove("three", 4)            //不会删除任何条目
        numbersMap.remove("three", 3)  
        println(numbersMap)