Kotlin快速入门系列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")            //可变MutableListval set = setOf(1,2,3,4,5)                          //不可变Set
val mutableSet = mutableSetOf("1","2","3")          //可变MutableSetval 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.mzph.cn/news/658765.shtml

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

相关文章

第九节HarmonyOS 常用基础组件21-ImageAnimator

1、描述 提供帧动画组件来实现逐帧播放图片的能力&#xff0c;可以配置需要播放的图片列表&#xff0c;每张图片可以配置时长。 2、接口 ImageAnimator() 3、属性 参数名 参数类型 描述 images Array<ImageFrameInfo> 设置图片帧信息集合&#xff0c;每一帧的帧…

Python实现avif图片转jpg格式并识别图片中的文字

文章目录 一、图片识别文字1、导包2、代码实现3、运行效果 二、avif格式图片转jpg格式1、导包2、代码实现3、运行效果4、注意事项 三、Python实现avif图片转jpg格式并识别文字全部代码 在做数据分析的时候有些数据是从图片上去获取的&#xff0c;这就需要去识别图片上的文字。P…

C# 多线程(2)——线程同步

目录 1 线程不安全2 线程同步方式2.1 简单的阻塞方法2.2 锁2.2.1 Lock使用2.2.2 互斥体Mutex2.2.3 信号量Semaphore2.2.3 轻量级信号量SemaphoreSlim2.2.4 读写锁ReaderWriterLockSlim 2.3 信号同步2.3.1 AutoResetEvent2.3.1.1 AutoResetEvent实现双向信号 2.3.2 ManualResetE…

【算法与数据结构】300、LeetCode最长递增子序列

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;   程序如下&#xff1a; class Solution { public:int lengthOfLIS(vector<int>& nums)…

函数高级.

函数高级 1. 函数嵌套1.1 函数在作用域中1.2 函数定义的位置1.3 嵌套引发的作用域问题练习题 2.闭包3.装饰器3.1 第一回合3.2 第二回合3.3 第三回合优化伪应用场景重要补充&#xff1a;functools 总结作业 各位小伙伴想要博客相关资料的话关注公众号&#xff1a;chuanyeTry即可…

广告营销为什么需要使用代理IP

在广告营销中使用代理IP有几个主要原因 绕过限制和封禁 某些广告平台或网站可能会限制或封禁特定IP地址或IP地址范围&#xff0c;以防止滥用或欺诈行为。使用代理IP可以帮助您绕过这些限制&#xff0c;使您能够在被封禁的IP范围之外进行广告投放。 地理定位和目标市场 广告…

知识点积累系列(六)操作系统(Linux+Windows+MacOS)篇【持续更新】

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 知识点积累 系列文章的第六篇&#xff0c;记录日常学习中遇到的 操作系统相关 的知识点&#xff0c;包括 Linux、Windows、MacOS等 1.Linux相关 1.1.shell脚本 1.2.命令相关 1.2.1.vim命令 1.2.2.nslookup命…

GPT-4 Vision调试任何应用,即使缺少文本日志 升级Streamlit七

GPT-4 Vision 系列: 翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式二翻译: GPT-4 Vision静态图表转换为动态数据可视化 升级Streamlit 三翻译: GPT-4 Vision从图像转换为完全可编辑的表格 升级St…

本地配置Joplin Server用于Joplin笔记同步并实现公网远程访问

文章目录 1. 安装Docker2. 自建Joplin服务器3. 搭建Joplin Sever4. 安装cpolar内网穿透5. 创建远程连接的固定公网地址 Joplin 是一个开源的笔记工具&#xff0c;拥有 Windows/macOS/Linux/iOS/Android/Terminal 版本的客户端。多端同步功能是笔记工具最重要的功能&#xff0c;…

LabVIEW潜油电泵数据采集系统

LabVIEW潜油电泵数据采集系统 介绍一个基于LabVIEW的潜油电泵数据采集系统。该系统目的是通过高效的数据采集和处理&#xff0c;提高潜油电泵的性能监控和故障诊断能力。 系统由硬件和软件两部分组成。硬件部分主要包括数据采集卡、传感器和电泵等&#xff0c;而软件部分则是…

IMX6LL|打造自己的驱动总线

xbus&#xff1a;打造自属的驱动总线 驱动总线 软件与硬件代码分离&#xff0c;提高程序的复用性 device–关联硬件代码driver_devices–关联软件代码bus_type–统一管理、设置match匹配规则 设备驱动模型体现分离思想 bus-xbus-devices-drivers 总线管理 buses_init()函…

鸿蒙系统扫盲(七):勘误补充总结,收个尾

这是笔者鸿蒙扫盲系列的最后一篇了&#xff0c;准备对过去的六篇扫盲系列文章&#xff0c;错误的地方做一些勘误&#xff0c;并且补充更新一些朋友们感兴趣的知识&#xff0c;最后收个尾。 1.勘误&#xff0c;编译型语言和解释型语言 在鸿蒙系统扫盲&#xff08;五&#xff0…

网工内推 | 网络安全工程师专场,大平台,六险一金

01 汽车之家 招聘岗位&#xff1a;高级网络安全工程师 职责描述&#xff1a; 1、负责公司网站、系统与产品的漏洞扫描、渗透测试与安全评估工作&#xff1b; 2、负责公司安全系统与安全设备的运维&#xff0c;负责公司网络安全监控管理&#xff1b; 3、负责公司安全事件的应急…

社区投稿|Desig质押聚合器功能,帮助用户选出更适合的质押策略

在Sui上&#xff0c;不同的质押协议提供收益各异的产品&#xff0c;因此用户面临着众多可以质押token的协议&#xff0c;眼花缭乱无从选择。Desig质押聚合器功能现已整合到Desig钱包扩展中&#xff0c;极大地简化了寻找质押策略的流程。事实上&#xff0c;其智能质押功能支持完…

记录:Windows上QML程序打包

0.本文修改记录 &#xff08;2019-9-3&#xff09; 修改了VC环境相关的内容 &#xff08;2020-3-5&#xff09; 修改了QML模块相关的内容 &#xff08;2022-8-31&#xff09;one-rabbit大佬指出打包命令的参数错误&#xff0c;根据文档可知&#xff1a;qmldir应该为exe对应项…

transformer_位置编码代码笔记

transformer_位置编码代码笔记 transformer输入的序列中&#xff0c;不同位置的相同词汇可能会表达不同的含义&#xff0c;通过考虑位置信息的不同来区分序列中不同位置的相同词汇。 位置编码有多种方式&#xff0c;此处仅记录正余弦位置编码 正余弦位置编码公式如下&#x…

宠物用品/宠物自动饮水机方案

宠物自动饮水机方案原理 宠物自动饮水机&#xff0c;也叫做智能宠物饮水机&#xff0c;是一种为宠物设计的智能化饮水器。应用核心主要在于智能化水泵控制&#xff0c;以及外围传感器电路。 宠物自动饮水机使用方便&#xff0c;不用频繁的换水。另外&#xff0c;自来水的水质可…

(6)Elastix图像配准:可视化配准工具

文章目录 前言一、配准工具1.1、基于Elastix的可视化配准工具1.1.1、elastix-napari&#xff1a;基于napari的Elastix图像配准1.1.2、SlicerElastix&#xff1a;基于3D slice的Elastix图像配准1.1.3、BIRDS&#xff1a;基于ImageJ的Elastix双通道图像配准 1.2、基于ITK开发的配…

微信小程序如何实现点击上传图片功能

如下所示,实际需求中常常存在需要点击上传图片的功能,上传前显示边框表面图片显示大小,上传后将图形缩放到边框大小。 实现如下: .wxml <view class="{{img_src==?blank-area:}}" style="width:100%;height:40%;display:flex;align-items: center;jus…

容器算法迭代器初识

#include<iostream> using namespace std; #include<vector> //vetor容器存放内置数据类型 void test01() {//创建了一个vector容器&#xff0c;数组 vector<int> v;//向容器中插入数据v.push_back (10);//尾插 v.push_back (20);v.push_back (30);v.push_ba…