Kotlin快速入门系列11

news2024/11/15 15:52:11

Kotlin的集合

集合类

Java类库有一套相当完整的容器集合类用来持有对象。跟Java一样,集合类存放的都是对象的引用,而非对象本身(我们经常说的集合指的是集合中对象的引用),Kotlin的集合类是在Java的集合类库基础上进行的优化,新引入了不可变集合类等扩展,相关类和API都在kotlin.collections包里

Kotlin的集合根据本身可变性可以分为两种可变集合类不可变集合类

常用的集合类主要有三种

·List(列表):List中的元素以线性方式存储,可以存放重复对象且列表中的元素是有序地排列。根据可变性分为只读不可变的List和可变MutableList(可写入、删除数据)。

·Set():存放的元素无序、不重复根据可变性分为不可变Set和可变MutableSet(可写入、删除数据)。

·Map(映射):持有的对象是“键值对”形式,每一个对象都包含一对键值Key-Value对象。其中key是唯一的,key决定对象在映射中的存储位置(但key本身并不能决定对象的存储位置,它通过哈希算法产生一个被称做哈希值的整数值,这个哈希值对应value的存储位置)。Map与List、Set一样,Map也分为只读Map和可变 MutableMap(可写入、删除数据)。需要注意的是,Map没有继承于Collection接口。

从数据结构的角度来看,List中的下标类似键值对中的Key, 只不过Key是有序的Int类型,所以说List也可以说是一种特殊的Map数据结构。而Set也是Key为Int类型,但是Value值是不能重复的特殊Map。

集合类接口

Kotlin中集合类接口的结构层次如图所示

各接口对应功能如下:

集合的创建

常用API:

· 可使用listOf()、setOf()、mapOf()函数创建不可变的List 容器、Set容器、Map容器。

· 可使用mutableListOf()、 mutableSetOf()、mutableMapOf()函数来创建可变的MutableList容器、MutableSet容器、MutableMap容器。

· 可使用emptyList<>()创建一个空的List对象,使用emptySet()创建一个空的只读Set,使用emptyMap<K,V>()创建一个空的Map。

· Map还有相关linkedHashMapOf()和haspMapOf()。常用的mapOf()和mutableMapOf()创建的对象性质类似Java的LinkedHashMap。

声明格式代码示例如下:

val list = listOf(1,2,3,4,5)                        //不可变List
val mutableList = mutableListOf("1","2","3")            //可变MutableList

val set = setOf(1,2,3,4,5)                          //不可变Set
val mutableSet = mutableSetOf("1","2","3")          //可变MutableSet

val map = mapOf(1 to "one",2 to "two",3 to "haha")                          //创建不可变Map
val mutableMap = mutableMapOf(1 to "one",2 to "two",3 to "haha")            //创建可变MutableMap

要想创建没有元素的空List,使用listOf()即可。不过创建空变量时,变量的类型不能省略(泛型),需要在声明时显式声明:

val emptyList: List<Int> = listOf() //显式声明List中的元素类型为Int
val emptyLIst2 = emptyList<Int>()

val emptySet: Set<Int> = setOf() //显式声明Set中的元素类型为Int
val emptySet2 = emptySet<Int>()

val emptyMap: Map<String,String> = mapOf() //显式声明Map中的元素类型为String,String键值对
val emptyMap2 = emptyMap<String,String>()

可以得出只读集合(listOf、setOf 和 mapOf)与可变集合(mutableList、mutableSetOf和 mutableMapOf)对应的kotlin&java集合的关系表:

方法

Java类型

listOf()

kotlin.collections.EmptyList

setOf()

kotlin.collections.EmptySet

mapOf()

kotlin.collections.EmptyMap

listOf(element: T)

java.util.Collections$SingletonList

setOf(element: T)

java.util.Collections$SingletonSet

mapOf(pair: Pair<K, V>)

java.util.Collections$SingletonMap

listOf(vararg elements: T)

java.util.Arrays$ArrayList

setOf(vararg elements: T)

java.util.LinkedHashSet

mapOf(vararg pairs: Pair<K, V>)

java.util.LinkedHashMap

mutableList()

java.util.ArrayList

mutableSetOf()

java.util.LinkedHashSet

mutableMapOf()

java.util.LinkedHashMap

元素遍历

List、Set类继承了Iterable接口,里面扩展了forEach函数来进行遍历元素操作;Map接口中也扩展了forEach函数来迭代遍历元素。示例如下:

fun main(args: Array<String>) {
    var list: List<Int> = listOf(1,2,3)

    list.forEach{
        print(it)          //打印123 ,set和map使用同理
    }

}

如果我们想在迭代遍历元素的时候访问index下标,在List和Set中可以使用forEachIndexed函数。如下示例:

fun main(args: Array<String>) {
    var list: List<String> = listOf("a","b","c")

    list.forEachIndexed { index: Int, i: String ->       //第1个参数是下标,第2个参数是list中元素类型
        println(" list key is $index and value is $i")
    }
}

对应看到的控制台输出为:

映射函数

即对集合中每一个元素应用给定的函数,并把结果收集到一个新集合。基本的映射函数是 map()。 它将给定的 lambda 函数应用于每个后续元素,并返回 lambda 结果列表。 结果的顺序与元素的原始顺序相同。如果还需要用到元素索引作为参数的转换,请使用 mapIndexed()(对比下上面的forEachIndexed(),有没有发现什么?)。示例如下:

fun main(args: Array<String>) {
    val number = setOf(1, 2, 3)
    println(number.map { it * 3 })                  //对应输出 [3, 6, 9]
    println(number.mapIndexed {     keys, value -> value * keys })  //对应输出[0, 2, 6]
}

如果转换的结果在某些元素上产生空值,则可以通过调用 mapNotNull() 函数取代 map() 或 mapIndexedNotNull() 取代 mapIndexed() 来从结果集中过滤掉 null 值。示例如下:

fun main(args: Array<String>) {
    val number = setOf(1, 2, 3, 4)
    println(number.map { if (it == 3) null else it * 2})
    println(number.mapNotNull { if (it == 3) null else it * 2})
    println(number.mapIndexed { keys, value -> if (keys == 2) null else value * keys })
    println(number.mapIndexedNotNull { keys, value -> if (keys == 2) null else value * keys })
}

对应的控制台结果为:

观察其源码,可以发现:

/**
 * 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)
}
/**
 * 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
}

这个过程,就是创建一个新的ArrayList集合,遍历原集合,将函数类型对象处理过的值添加到新ArrayList对象中,并返回新的ArrayList对象。

此外,映射转换时,有两个选择:转换键,使值保持不变,反之亦然。 要将指定转换应用于键,请使用 mapKeys();反过来,mapValues() 转换值。 这两个函数都使用将映射条目作为参数的转换,因此可以操作其键与值。示例如下:

fun main(args: Array<String>) {
    val number= mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 4)
    println(number.mapKeys { it.key })
    println(number.mapValues { it.value + it.key.length })
}

对应控制台输出为:

此外kotlin还有一个flatten()函数,用法在理解上是跟map()相反的场景,使用场景较少,这里不做重复介绍了。

过滤函数

filter()是kotlin最常用的高阶函数之一,作用就是过滤。它可以对Collection集合、Map集合或数组元素进行过滤,Collection集合和数组返回的是一个List集合,Map集合返回的还是一个Map集合。

fun main(args: Array<String>) {
    val numbers = listOf("one", "two", "three", "four")
    val newNumbers = numbers.filter { it.length > 3 }
    println(newNumbers)

    val numbersMap = mapOf("key10" to 1, "key2" to 2, "key30" to 3, "key4" to 4)
    val newMaps = numbersMap.filter { (key, value) -> key.endsWith("0") && value > 2}
    println(newMaps)
}

对应的控制台输出为:

与上述的map()类似,filter也有filterIndexed()(返回索引和值)和filterNot()(过滤空对象):

fun main(args: Array<String>) {
    val numbers = listOf("one", "two", "three", "four")
    val newNumbersOne = numbers.filter { it.length <= 3 }
    val newNumbersTwo = numbers.filterIndexed { index, s -> (index != 0) && (s.length < 5) }
    val newNumbersThree = numbers.filterNot { it.length <= 3 }
    println(newNumbersOne)
    println(newNumbersTwo)
    println(newNumbersThree)
}

对应输出结果为:

我为什么说这个使用场景较多呢,假设你现在有几个Bean对象,要拿Bean对象的某一个属性进行对比(不一定是比大小),然后获取对比后的数据,就可以用到fliter()(这个场景在实际开发过程中很常见)。例如如下示例:

data class Students (val id: Int,var name:String,var age:Int,var score:Int)

fun main(args: Array<String>) {
    var studentList = listOf(
        Students(1,"jack",18,88),
        Students(2,"nick",19,86),
        Students(3,"James",20,99)
    )
    val student = studentList.filter { it.age > 18 }   //过滤出studentList中年龄大于18的
    println(student)
}

对应控制台输出为:

排序函数

Kotlin集合类中提供了倒序排列集合元素的函数reversed(),具体使用与Java的reversed()一样。示例如下:

fun main(args: Array<String>) {
    val list = listOf(1,2,3,4,5)
    val set = setOf("abc","jkl","zvm")
    list.reversed()
    set.reversed()
    println(list)           //对应输出[1, 2, 3, 4, 5]
    println(set)            //对应输出[abc, jkl, zvm]
}

对应的升序排序函数是sorted(),使用方法也跟Java一样,不做赘述:

fun main(args: Array<String>) {
    val list = listOf(9,2,4,6,1)
    val set = setOf(5,3,6)
    println(list.sorted())           //对应输出[1, 2, 4, 6, 9]
    println(set.sorted())            //对应输出[3, 5, 6]
}

元素去重

distinct()函数,功能描述即去除集合内的重复性元素。list和set可以使用,map不行(这个可以猜到的吧)。示例如下:

fun main(args: Array<String>) {
    val list = listOf(9,2,9,4,1,1,4,6,1)
    val set = setOf(5,3,5,6,1,6)
    println(list.distinct())           //对应输出[9, 2, 4, 1, 6]
    println(set.distinct())            //对应输出[5, 3, 6, 1]
}

使用方式简单,这里不做赘述。

End,如有其他问题请留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1424091.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

-1- Python环境安装

1、Python安装 1.1、Windows安装Python 进入python官网&#xff1a;Welcome to Python.org点击 download——>all releases&#xff1b;建议选择3.7.2版本&#xff08;网页链接&#xff1a;Python Release Python 3.7.2 | Python.org&#xff09;&#xff1b;下拉&#xf…

【C++】默认成员函数

与普通成员函数差距较大&#xff0c;形式对于我们比较陌生&#xff0c;但这是语法&#xff0c;是我们是必须要掌握的。 目录 类的默认成员函数&#xff1a;构造函数&#xff1a;概念&#xff1a;语法&#xff1a;特性&#xff1a; 析构函数&#xff1a;概念&#xff1a;语法&a…

rp-bf:一款Windows下辅助进行ROP gadgets搜索的Rust库

关于rp-bf rp-bf是一款Windows下辅助进行ROP gadgets搜索的Rust库&#xff0c;该工具可以通过模拟Windows用户模式下的崩溃转储来爆破枚举ROP gadgets。 在很多系统安全测试场景中&#xff0c;研究人员成功劫持控制流后&#xff0c;通常需要将堆栈数据转移到他们所能够控制的…

Spark入门01-Spark简介

1 Spark是什么 Spark是用于大规模数据处理的统一分析引擎。对任意类型的数据进行自定义计算。 可以计算&#xff1a;结构化、非结构化&#xff0c;半结构化的数据结构&#xff0c;支持使用Python&#xff0c;Java&#xff0c;Scala、Sql语言开发应用程序计算数据。 计算框架&a…

一文掌握SpringBoot注解之@Configuration知识文集(1)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

不同生态系统蒸散发研究进展_刘超_2023

不同生态系统蒸散发研究进展_刘超_2023 摘要关键词 1 研究方法1.1 实测法1.1.1 蒸渗仪1.1.2 气孔计法1.1.3 化学示踪法1.1.4 大孔径闪烁仪1.1.5 涡动相关法 1.2 模型法1.2.1 水量平衡法1.2.2 波文比-能量平衡法1.2.3 遥感技术1.2.4 综合法和辐射法 2 研究展望2.1 研究进展2.2 存…

使用 Docker 部署扫雷小游戏

1&#xff09;源码 介绍&#xff1a;扫雷游戏是一款经典的单人益智游戏&#xff0c;旨在通过揭示方块和避开地雷来展示玩家的逻辑思维和推理能力。 源码&#xff1a;saolei.zip 个人文件站&#xff1a;https://share.wuhanjiayou.cn/ 2&#xff09;部署 2.1&#xff09;安装…

中科大计网学习记录笔记(一):Internet | 网络边缘

计算机网络 前言&#xff1a; 学习视频&#xff1a;中科大郑烇、杨坚全套《计算机网络&#xff08;自顶向下方法 第7版&#xff0c;James F.Kurose&#xff0c;Keith W.Ross&#xff09;》课程 该视频是B站非常著名的计网学习视频&#xff0c;但相信很多朋友和我一样在听完前面…

学习嵌入式第十五天之结构体

用变量a给出下面的定义 a) 一个整型数&#xff08;An integer&#xff09; //int a;b) 一个指向整型数的指针&#xff08;A pointer to an integer&#xff09; //int *a;c) 一个指向指针的的指针&#xff0c;它指向的指针是指向一个整型数&#xff08;A pointer to a poin…

通用CI/CD软件平台TeamCity全新发布v2023.11——增强Git托管平台的集成

TeamCity是一个通用的 CI/CD 软件平台&#xff0c;可以实现灵活的工作流、协作和开发做法。我们的解决方案将帮助在您的 DevOps 流程中成功实现持续集成、持续交付和持续部署。 TeamCity 2023.11正式版下载 TeamCity 2023.11 带来了矩阵构建和构建缓存等多项备受期待的功能&a…

Redis -- 单线程模型

失败是成功之母 ——法国作家巴尔扎克 目录 单线程模型 Redis为什么这么快 单线程模型 redis只使用一个线程&#xff0c;处理所有的命令请求&#xff0c;不是说redis服务器进场内部真的就只有一个线程&#xff0c;其实也有多个线程&#xff0c;那就是处理网络和io的线程。 R…

计算机设计大赛 深度学习 opencv python 实现中国交通标志识别_1

文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 &#x1f525; 优质…

【零基础学习CAPL】——CAN报文的发送(按下按钮同时周期性发送)

🙋‍♂️【零基础学习CAPL】系列💁‍♂️点击跳转 文章目录 1.概述2.面板创建3.系统变量创建4.CAPL实现4.1.函数展示4.2.全量报文展示5.效果1.概述 本章主要介绍使用CAPL和Panel在按下按钮时发送周期性CAN报文。 本章主要在“【零基础学习CAPL】——CAN报文的发送(配合P…

即时设计和xd对比有什么优势?

Adobe XD 是 Adobe 公司推出的用户体验设计工具主要用于创建和设计用户界面的原型和设计草案&#xff0c;如网站、移动应用程序和桌面应用程序。然而&#xff0c;由于其复杂的功能使用和全英文操作界面&#xff0c;许多设计师被说服离开。Adobe XD 这是一款价格相对较高的商业软…

【微服务】Spring Boot集成ELK实用案例

推荐一款我一直在用国内很火的AI网站&#xff0c;包含GPT3.5/4.0、文心一言、通义千问、智谱AI等多个AI模型&#xff0c;支持PC、APP、VScode插件同步使用&#xff0c;点击链接跳转->ChatGPT4.0中文版 一、前言 在现代软件开发中&#xff0c;微服务架构已成为一种流行趋势。…

Kafka运维相关知识

目录 一、基本概念 二、技术特性 三、设计思想 四、运维建议 一、基本概念 Apache kafka 是一个分布式的基于push-subscribe的消息系统&#xff0c;它具备快速、可扩展、可持久化的特点。它的最大的特性就是可以实时的处理大量数据以满足各种需求场景&#xff1a;比如基于h…

辽宁链家新房数据采集与可视化实现

摘 要 网络爬虫也叫做网络机器人&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取网络信息&#xff0c;进行数据信息的采集与整理的程序或者脚本。随着海量数据的出现&#xff0c;如何快速有效的获取到我们想要的数据成为难题。以房源信息为例&#xff0c;该文使用Pyt…

【JAVE SE】---运算符和程序逻辑控制语句

1.运算符 算数运算符 - * / % 注意&#xff1a;1.Java的%符号左右两边可以是小数&#xff0c;也可以是负数 //运算符float a1.0f;float b2.0f;float c-1.5f;System.out.println(a%b); //1.0System.out.println(a%c); //1.0 2.Java中除数不可以为0&#xff0c…

华为配置ARP安全综合功能实验

配置ARP安全综合功能示例 组网图形 图1 配置ARP安全功能组网图 ARP安全简介配置注意事项组网需求配置思路操作步骤配置文件 ARP安全简介 ARP&#xff08;Address Resolution Protocol&#xff09;安全是针对ARP攻击的一种安全特性&#xff0c;它通过一系列对ARP表项学习和A…

如何用MapTalks IDE来发布网站?

简介 MapTalks IDE 全称 MapTalks集成设计环境&#xff08;Integrated Design Environment&#xff09;&#xff0c;是由MapTalks技术团队开发的新一代web地图设计软件。 通过MapTalks IDE&#xff0c;您可以自由的创建二维和三维地图&#xff0c;在其中载入或创建地理数据&a…