• 【Kotlin精简】第2章 集合


    1 简介

    Kotlin 中集合主要分为可变集合只读集合,其中可变集合使用 “Mutable” 前缀 + 集合类名表示,比如 MutableListMutableSetMutableMap 等。而对于只读集合就是和 Java 中集合类名是一致。 Java 中的 List 非 Kotlin 中的 List , 因为 Kotlin 中的 List 是只读的而非可变,却有点类似于 Kotlin 中的 MutableList
    在这里插入图片描述

    1. 只读集合:
      内部只具有访问元素的方法,不具有类似 add、remove、clear 之类修改集合的方法。比如 Collection 只读集合内部就没有 add、remove、clear 之类方法,只有 get 访问元素的方法.
    2. 可变集合
      在集合内部既具有访问元素的方法,也具有类似 add、remove、clear 之类修改集合的方法。比如 MutableCollection 可变集合内部就有 addremoveclear 之类方法。

    集合是可变数量的一组条目。
    List : 是有序集合,可以通过下标访问元素,元素可以重复。
    Set : 是无序集合,有别于List集合的地方在于,1.没有下标,2.元素不允许重复。只能遍历获取参数,遍历参数的顺序与添加顺序相同。元素如果已经存在不进行添加。可以存储Null, 而且Null也是唯一的。
    Map:是无序集合,通过键值对存储数据。每个键唯一。值可以重复。

    集合主要就是ListSetMap,它们在Java中都有接口可以实现,
    List --> ArrayList、LinkedList
    Set --> HashSet
    Map–> HashMap

    1.1 List集合

    	val list = ArrayList<String>()
    	list.add("1")
    	list.add("2")
    	
    	// 创建的是一个不可变的集合,该集合创建成功只能用于读取数据,不能增删改集合数据。
    	val list1 = listOf("aa", "bb")
    	// 创建的是一个可变的集合,可以进行增删改查操作。
    	val list2 = mutableListOf("cc", "dd")
    	
    	// 遍历List集合需要使用for-in循环进行遍历
    	for (content in list1){
    		// 把遍历内容大写
    		content.toUpperCase()
    		print(content)	// 输出:aa bb
    	}
    	
    	list2.add("ee")
    	list2.addAll(list1)
    	// 移除指定的元素对象。如果指定元素不存在,移除null。不会报错
    	list2.remove("ee")
    	// 移除参数集合中存在的所有元素。 
       	// 或者,你可以关键字作为参数来调用它;在这种情况下,函数移除关键字匹配true 的所有元素。
    	list2.removeAll(list1)
    	// retainAll() 与 removeAll() 相反,
       	// 它移除除参数集合中的元素之外的所有元素。
       	// 当与关键字一起使用时,它只留下与关键字匹配的元素。
    	list2.retainAll(list)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    1.2 Set集合

    Set和List的用法其实一样,在初始化时会用到这几个方法:setof()mutableSetOf()

    	// 不可变的集合
    	val set1 = setOf("aa", "bb") 
    	// 可变的集合
    	val set2 = mutableSetOf("cc", "dd") 
    
    	// 新增元素
       	set2.add("ee")
       	set2.addAll(set1)
       	
    	// 移除指定的元素对象。如果指定元素不存在,移除null。不会报错
       	set2.remove("ee")
       	// 移除参数集合中存在的所有元素。 
       	// 或者,你可以关键字作为参数来调用它;在这种情况下,函数移除关键字匹配true 的所有元素。
       	set2.removeAll(set1)
       	// retainAll() 与 removeAll() 相反,
       	// 它移除除参数集合中的元素之外的所有元素。
       	// 当与关键字一起使用时,它只留下与关键字匹配的元素。
       	set2.retainAll(set1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    setof():创建的是一个不可变的集合,该集合创建成功只能用于读取数据,不能增删改集合数据。
    mutableSetOf():创建的是一个可变的集合,可以进行增删改查操作。
    在这里,Set集合List集合的区别需要注意的是,Set底层是使用Hash映射机制来存储数据的,因此集合中的元素无法保证有序。
    ----遍历和List一样,就不做解释了

    1.3 Map集合

    Map集合这里重点介绍,Map和前两者不同,Map是一种键值对形式的数据结构,因此在用法上和List、Set存在很大不同。
    一般初始化Map时都需要创建一个HashMap

    val map = HashMap<String, String>()
    map.put("aa", "1")
    map.put("bb", "2")
    
    // 因为在Kotlin中,并不建议使用put()、get()方法对Map进行添加和读取数据,
    // 而是使用这种类似下标的方式添加数据:
    val map1 = HashMap<String, Int>()
    map1["aa"] = 1
    map1["bb"] = 2
    
    // 当读取数据时
    val text = map1["aa"]
    
    // 移除对应的值,参数为key
    map1.remove("aa")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    然而,上面这种添加数据方式依然很繁琐,和List、Set一样,Map也有自己的方法mapof()、mutableMapOf()

    // 不可变
    val map1 = mapOf("aa" to 1, "bb" to 2)  
    // 可变
    val map2 = mutableMapOf("aa" to 1, "bb" to 2)  
    
    • 1
    • 2
    • 3
    • 4

    mapof():创建的是一个不可变的集合,该集合创建成功只能用于读取数据,不能增删改集合数据。
    mutableMapOf():创建的是一个可变的集合,可以进行增删改查操作。
    遍历Map集合,也是使用的for-in循环,唯一区别在于,for-in循环中,map键值对变量一起申明到了一对括号中

    fun main(){
        val map1 = mapOf("aa" to 1, "bb" to 2) 
        for ((content1, content2) in map1){
            print(content1 + "--" + content2)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1.4 集合迭代器 Iterator

    提供一种遍历集合元素的方法,而不暴露集合内部的实现。

    1.4.1 迭代器的方式

    只要实现了Iterable接口的类型,都提供迭代器。
    下面是使用迭代器的3种方式:

    1. 使用next()
    val numbers = listOf("one", "two", "three", "four")
    val numbersIterator = numbers.iterator()
    while (numbersIterator.hasNext()) {
        println(numbersIterator.next())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 使用for…in
    val numbers = listOf("one", "two", "three", "four")
    for (item in numbers) {
        println(item)
    }
    
    • 1
    • 2
    • 3
    • 4
    1. 使用forEach()
    val numbers = listOf("one", "two", "three", "four")
    numbers.forEach {
        println(it)
    }
    
    • 1
    • 2
    • 3
    • 4

    1.4.2 List 的迭代器

    List 的迭代器是ListIterator类型,可以反向迭代:

    val numbers = listOf("one", "two", "three", "four")
    val listIterator = numbers.listIterator()
    while (listIterator.hasNext()) listIterator.next()
    println("Iterating backwards:")
    while (listIterator.hasPrevious()) {
        print("Index: ${listIterator.previousIndex()}")
        println(", value: ${listIterator.previous()}")
    }
    
    // Iterating backwards:
    // Index: 3, value: four
    // Index: 2, value: three
    // Index: 1, value: two
    // Index: 0, value: one
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.4.3 可变迭代器

    可变集合(MutableList, MutableSet, MutableMap)的迭代器都是MutableIterator类型,可以在迭代的过程中调用remove()方法删除元素。

    val numbers = mutableListOf("one", "two", "three", "four") 
    val mutableIterator = numbers.iterator()
    
    mutableIterator.next()
    mutableIterator.remove()
    
    println("After removal: $numbers")
    // After removal: [two, three, four]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    另外,MutableList的迭代器是MutableListIterator类型,可以在迭代过程中插入替换元素。

    val numbers = mutableListOf("one", "four", "four") 
    val mutableListIterator = numbers.listIterator()
    
    mutableListIterator.next()
    mutableListIterator.add("two")
    mutableListIterator.next()
    mutableListIterator.set("three")
    
    println(numbers)
    // [one, two, three, four]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1.5 集合Range

    使用rangeTo()可以创建范围,rangeTo()对应的操作符:…。

    // 遍历范围
    for (i in 1..4) print(i)
    
    // 反序遍历:
    for (i in 4 downTo 1) print(i)
    
    // 反序遍历2:
    for (i in (1..4).reversed()) print(i)
    
    // 定义步长:
    for (i in 1..8 step 2) print(i)
    
    // 不包含末尾元素:
    for (i in 1 until 10) print(i)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.6 集合序列 Sequence

    序列和迭代器的差别
    Iterable遍历执行多步操作时,会先对所有元素执行一个步骤,将结果保存到中间集合中,然后再对中间集合中所有元素执行下一个步骤,以此类推。相当于,所有元素被并行处理。

    Sequence遍历执行多步操作时,会对一个元素执行所有步骤,然后再对下一个元素执行所有步骤,以此类推。相当于,所有元素被串行处理。

    // 1.通过元素创建
    val s1 = sequenceOf(1, 2, 3)
    
    // 2.通过Iterable创建
    val list = listOf(1,2,3)
    val s2 = list.asSequence()
    
    // 3.通过generateSequence()函数创建
    
    // 4.通过sequence()创建
    
    
    // 例子:假设有很多单词,我们要过滤长度超过3个字母的单词,然后打印前4个这种单词的长度。
    // Iterable的方式
    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)
    
    // Sequence的方式
    val words = "The quick brown fox jumps over the lazy dog".split(" ")
    // 将 List 转换为序列
    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")
    // 终止操作: 以 List 形式获取结果
    println(lengthsSequence.toList())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    1. filter()map()take()这些操作,在调用toList()后才开始执行。与上面Iterable相比,是”lazy“的。
    2. 当结果元素数量到达4个时,会停止处理,因为take(4)指定了最大元素数量。与上面Iterable相比,节省了操作步骤。
    3. Sequence处理执行了 18 步,而使用Iterable时则需要 23 步。

    1.7 常用的集合函数式API

    1.7.1 map()函数

    它用于将每个元素都映射成一个另外的值,映射规则在Lambda表达式中指定,最终生成一个新的集合,

    val list1 = listOf("aa", "bb") 
    var newList = list1.map{ it.toUpperCase()}
    for (content in list1){
        content.toUpperCase() //转换成大写模式
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.7.2 filter()函数

    用于过滤集合中的数据,可以单独使用,也可以和map()一起使用

    val list1 = listOf("aa", "bbbb", "cc") 
    var list2 = list1.filter { it.length <= 2 }
                             .map { it.toUpperCase() }
    
    • 1
    • 2
    • 3

    1.7.3 any()函数

    判断集合中是否至少存在一个元素满足指定条件

    val list1 = listOf("aa", "bbbb", "cc") 
    var anyResult = list1.any { it.length <= 2 }
    
    • 1
    • 2

    1.7.4 all()函数

    判断集合中是否所有元素都满足指定条件

    val list1 = listOf("aa", "bbbb", "cc") 
    var allResult = list1.all { it.length <= 2 }
    
    • 1
    • 2

    1.7.5 maxBy()函数

    定义一个集合,然后找出里面长度最长的元素,maxBy的工作原理是根据传入的条件来进行遍历,从而找打最大值

    val list1 = listOf("aa", "bbbb", "cc") 
    var maxLength = list1.maxBy { it.length }
    print(maxLength)
    
    • 1
    • 2
    • 3
  • 相关阅读:
    K8S-Helm和相关组件(Dashboard、Prometheus、EFK)
    Spark—GraphX编程指南
    三、IPSec
    2024年新版宝塔面板如何安装WordPress网站教程
    Superset embed Dashboard到React App
    【使用工具】IDEA创建类及已有类添加注释-详细操作
    LVM_基本操作
    某城商行双活建设方案设计与实施经验分享
    Echarts渲染不报错但是没有内容
    [FBCTF2019]RCEService
  • 原文地址:https://blog.csdn.net/u010687761/article/details/133648758