Kotlin学习之集合

原文链接 Kotlin Collections

现代的软件一般比较复杂,程序语言中的基本数据类型往往不能满足需要,除了基本的数据类型以外,还有对象的容器也非常的重要,比如线性容器(数组,列表和Set)和二维容器(哈希表)等。今天就来学习一下Kotlin中的容器。

Kotlin Collections

集合就是用于处理一组对象的容器,因为用的人较多,所以就成了标准库。常见的集合有三种主要类型,列表类,Set类和Map类。

线性容器

这里并不单纯指类List,主要的意思是线性的容器,它的特点是以相对顺序存储同一类型的对象,有一个整数索引(index)来表示其相对的位置,查找性能差,其他还好。代表为数组。

数组

最简单也是使用最为广泛的线性容器,不用过多的介绍了,可以参考之前的文章。

最大的弊端就是长度是固定的,长度在创建数组时就确定了,后面就改不了了。所以,必须在事先要能够确定数组的长度

创建复杂数组

比如数组的元素是一个Collection,而非常见的基本数据类型,这时要如何写?

       val carray = arrayOf<MutableList<Int>>(
            mutableListOf(),
            mutableListOf()
        )

        val narray = Array<MutableList<Int>>(10) { mutableListOf() }

关键就在于要声明元素的类型,其他的与基本数据类型的数组是一样的。另外,如果数组数量比较少,方便直接写,那就用字面构造函数,其实很方便。或者用数组元素的构造方法也可以。

多维数组

以最为常见的二维数组来说,要如何创建?

       val smatrix = arrayOf(
            arrayOf(1, 2, 3),
            arrayOf(4, 5, 6),
            arrayOf(7, 8, 9)
        )

        val matrix = Array(5) { IntArray(6) }

Ranges

用于表示区间的表达式,最为直观理解就是数组的索引,用操作符…来表示区间,比如0~9,就是0…9,通常用于for-loop中:

if (i in 1..4) { // equivalent of i >= 1 && i <= 4
    print(i)
}

for (i in 1..4) print(i) // for (int i = 1; i <= 4; i++) print(i)

还可以指定步长和边界,以及方向:

for (i in 0 until 10) { // for (int i = 0; i < 10; i++)
    print(ln)
}

for (i in 0 until 10 step 2) { // for (int i = 0; i < 10; i += 2)
    print(ln)
}

for (i in 9 downTo 0) { // for (int i = 9; i >= 0; i--)
    print(i)
}

还可以用于字符,比如:

for (c in 'a'..'z') { // for (char c = 'a'; c <= 'z'; c++)
    print(c)
}

Range是一个表达式,所以在其之上做其他操作,但需要注意这时需要加上括号,比如:

    for (i in (0..9).filter {it % 2 == 0 }) {
        println(i) // only evens
    }
    for (c in ('a'..'z').map { it.toUpperCase() }) {
        println(c) // upper case
    }

需要注意,虽然Ranges方便操作数组的索引,但如果想要带着索引遍历数组的话,还是要用专用的遍历方式,而不是用Range,比如:

for ((index, value) in array.withIndex()) {
    println("the element: [$index] = $value")
}
注意与repeat的区别

Ranges是一个数据结构代表着一个区间,这个区间可能是一个整数范围,也可能是一个字符范围,其实也可以是其他自定义数据类型,只要能表达 出区间的概念。只不过整数区间是为常用的一种方式,以及整数区间可以方便当作数组和列表的索引。

但有时如果仅仅想重复一件事情n次,那就没有必要用Ranges,虽然它也可以,这时最为方便的是函数repeat,它与区间的唯一区别是repeat是没有返回值的,它仅是把一件事情重复n次,但没有返回值也就是说没有办法再转化为其他数组或者列表。

repeat(10) { println("repeat # $it") }
//repeat # 0
//repeat # 1
//repeat # 2
//repeat # 3
//repeat # 4
//repeat # 5
//repeat # 6
//repeat # 7
//repeat # 8
//repeat # 9

而比如Ranges是可以转化为其他数组和列表的:

(0 until 5).map { it * it }.toIntArray()
// [0, 1, 4, 9, 16]

列表List

列表可以简单理解为无限长的数组,它最大的特点是长度不固定,不必事先定好长度,它会随着添加元素而自动增长。所以,当你事先不知道容器的长度时,就需要用List。它是一个泛型,其余操作与数组一样。

val names = listOf("James", "Donald", "Kevin", "George")
names.map { it.toUpper() }
	.forEach { println(it) }

序列Sequence

序列与列表比较难区分,直观上它们是一样的。简单来说它并不是容器,它并不持有对象,它生产对象,类似于物理上的信号发射器和RxJava中的Observable,是有时序上的概念的,当你需要时它就生产出来一个元素。

队列queue

队列可以用双端队列deque(读作dek),具体实现对象是ArrayDeque<T>。

双端队列是强大的数据结构,即可以用作队列,也可以用作栈。

Set容器

Set是一个不含有重复元素的容器,特点是不会保存相对顺序,可以快速实现检索

    val names = setOf("James", "Harden", "Donald", "Joe")
    for (nm in names) {
        println(nm)
    }
    names.filter { it.length > 4 }
        .forEach { println(it) }

Map容器

由映射键->值对组成的二维容器,键不可重复,值可以重复,不会保存相对顺序,也可以用于快速检索。

    val nameMap = mapOf("James" to 15, "Harden" to 30, "Donald" to 80, "Joe" to 86)
    for (nm in nameMap.keys) {
        println(nm)
    }
    for (age in nameMap.values) {
        println(age)
    }
    for (e in nameMap.entries) {
        println("${e.key} is ${e.value}")
    }
    nameMap.filter { it.key.length > 5 }
        .forEach { println("${it.key} = ${it.value}") }

注意Immutability

有一个地方需要特别注意,那就是容器的不可变性Immutability,用常规的方法创建的集合对象是不可变的Immutable,就是无法向其中添加元素也无法删除元素。对象的不可变Immutable在函数式编程中是很重要的特性可以有效的减少异步和并发带来的状态一致性问题

val names = listOf("James", "Donald", "Kevin", "George")
names.add("Paul") // compile error, names is immutable
names.map { it.toUpper() }
	.forEach { println(it) }

这样写会有编译错误,因为用listOf创建的列表对象是不可变的Immutable。如果想要改变就必须用支持更改的对象,如MutableList, MutableSet和MutableMap,如:

val names = mutableListOf("James", "Donald", "Kevin", "George")
names.add("Paul") // okay
names.map { it.toUpper() }
	.forEach { println(it) }

如果有可能还是要尽可能的用不可变对象(Immutable objects)

集合的操作

集合的操作就是函数式的三板斧过滤filter,转化map和折叠化约fold/reduce,前面讲的所有的容器都是支持的,结合lambdas可以写出非常规范的函数式代码。

参考资料

  • Kotlin Collections
  • Kotlin常用Collection集合操作整理
  • Kotlin Collections Guide
  • Kotlin Ranges

原创不易,打赏点赞在看收藏分享 总要有一个吧

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python提取PDF表格(基于AUTOSAR_SWS_CANDriver.pdf)

个人学习笔记&#xff0c;仅供参考。 需求&#xff1a;提取AUTOSAR SWS中所有的API接口信息&#xff0c;用于生成C代码。 此处以AUTOSAR_SWS_CANDriver.pdf为例&#xff0c;若需要提取多个SWS文件&#xff0c;遍历各个文件即可。 1.Python包 pdfplumber是一款完全用python开…

销量上不去,消费者纷纷回归直屏,折叠手机成为电子垃圾

折叠手机成为安卓手机创新的噱头&#xff0c;不过随着更多消费者使用了折叠手机&#xff0c;折叠手机正迅速走下神坛&#xff0c;用过的消费者都说体验太差&#xff0c;纷纷抛弃这种手机&#xff0c;而在二手市场价格又达到骨折&#xff0c;可以说折叠手机正成为电子垃圾。 折叠…

Ilya Sutskever:师从Hinton,“驱逐”奥特曼,一个改变AI世界的天才科学

ChatGPT 已经在全球爆火&#xff0c;但大众在两周之前似乎更熟悉Sam Altman&#xff0c;而对另一位创始人 Ilya Sutskever 却了解不多。 直到前几天因为OpenA眼花缭乱的政权争夺大戏&#xff0c;OpenAI 的首席科学家Ilya Sutskever的名字逐渐被世人所知。 Ilya Sutskever在科…

Win7 SP1 x64 安装 Python 出错解决方法

1 双击安装 python-3.7.9.exe &#xff0c;提示出错&#xff0c;log.file 显示需要 KB2533623&#xff0c;但在Microsoft Update Catalog 没有搜到&#xff0c;实验 KB4474419 也可以。 2 Microsoft Update Catalog 搜索 KB4474419 并下载&#xff0c;安装&#xff0c;重启电脑…

如何使用ArcGIS Pro制作一张北极俯视地图

地图的表现形式有很多种&#xff0c;经常我们看到的地图是以大西洋为中心的地图&#xff0c;还有以太平洋为中心的地图&#xff0c;今天要给大家介绍的地图是从北极上方俯视看的地图&#xff0c;这里给大家讲解一下制作方法&#xff0c;希望能对你有所帮助。 修改坐标系 制作…

前端开发学习 (三) 列表功能

一、列表功能 1、列表功能 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compa…

组装自己的稳定扩散模型

在本文中&#xff0c;我们将利用 Hugging Face Diffusers 库的组件实现自己的稳定扩散模型&#xff0c;可以像 diffuser.diffuse() 一样简单地生成图像。 在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编…

sqli-labs靶场详解(less11-less16)

目录 less-11 less-12 less-13 less-14 less-15 less-16 提交参数后 动态参数不存在url中 存在于post表单中 于是在表单中进行注入点测试 先看一看这种提交数据的关卡输入提交后会有什么反应 unameadmin&passwdadmin&submitSubmit 输出 usernameadmin passwordadmin un…

mongodb查询数据库集合的基础命令

基础命令 输入show dbs 命令&#xff0c;查看数据库 db查看当前正处在哪个数据库 创建或进入要使用的数据库&#xff0c;命令&#xff1a;use 数据库名字 刚创建的数据库数据库名字 并不在数据库的列表中&#xff0c; 要显示它&#xff0c;我们需要向 数据库名字 数据库插…

MFC哈希实现 目标:知道初始密码的人,才能改密码及登录。只知道登录密码只能登录。避免密码直接写在代码里或本地,通过软件评估报告。----安全行业基础5

一种简单的登录设计&#xff0c;密码保存在本地。&#xff08;直接MD5不安全&#xff0c;别人可以更换本地的密码,得再加一层算法就相对安全一点&#xff09; 当然也可以用加密机或专门存密码的系统来实现&#xff0c;就过于复杂。目标&#xff1a;1、为了避免密码直接写在代码…

使用shell快速查看电脑曾经连接过的WiFi密码

此方法只能查看以前连接过的wifi名称和对应的密码 查看连接过的WiFi名称netsh wlan show profiles查看具体的WiFi名称netsh wlan show profile name"你的wifi名称" keyclear

plt绘制表格

目录 1、绘制简单表格 2、将字体居中 3、为每个表格添加背景 4、添加透明度 5、不显示表格标题 6、将pandas的表格列转行显示 7、关闭表格边框 8、设置表格长宽、字体大小 9、利用色系指定表格颜色 10、修改字体颜色、边框粗细 1、绘制简单表格 import pandas as pd…

「阿里巴巴」裁撤量子实验室!

据内部消息&#xff0c;阿里巴巴达摩院由于预算及盈利等原因&#xff0c;已经撤裁旗下量子实验室。此次&#xff0c;共计裁减30余人。 达摩院官网已撤下量子实验室的相关介绍页面。上图&#xff1a;早先关于量子实验室的相关介绍&#xff1b;下图&#xff1a;现在达摩院官网“实…

十分钟搭建VScode C/C++运行环境

一、下载配置vscode 1.下载安装VScode 地址&#xff1a;https://code.visualstudio.com/download 下载后&#xff0c;运行安装程序 (VSCodeUserSetup-{version}.exe)。这只需要一分钟。安装程序会将 Visual Studio Code 添加到环境变量中%&#xff0c;可以使用CMD键入“code”…

主播直播表现力

主播表现力:全面提升你的直播效果 一、语言表达 主播的语言表达是直播的关键。优秀的语言表达能够让观众感到亲切和舒适&#xff0c;增加观众的参与度和忠诚度。以下是一些提升语言表达的建议: 1.清晰简洁:尽量使用简单易懂的词汇和句子结构&#xff0c;避免过于复杂的表达。…

C#实体类与XML互转以及List和DataTable转XML的使用

引言 在C#开发中&#xff0c;数据的存储和传输是非常常见的需求。使用XML作为数据格式有很多优点&#xff0c;例如可读性强、易于解析等。而实体类、List和DataTable是表示数据模型的常用方式。本文将介绍如何在C#中实现实体类、List和DataTable与XML之间的相互转换&#xff0c…

好用的样式动画库集合(css、js)

文章目录 前言一、Animate.css二、Anime.js三、CSShake四、Hover.css五、AniJS六、Animista七、Tachyons-animate八、Sequence.js九、Infinite十、OBNOXIOUS.CSS十一、MOTION UI十二、Keyframes.app十三、AnimXYZ十四、Whirl十五、Hamburgers十六、Vivify十七、Magic Animation…

【2021研电赛】智能胸外按压电除颤一体仪

本作品介绍参与极术社区的有奖征集|分享研电赛作品扩大影响力&#xff0c;更有重磅电子产品免费领取! 团队介绍 参赛单位&#xff1a;上海理工大学 参赛队伍&#xff1a;上理电感队 指导老师&#xff1a;闫士举 参赛队员&#xff1a;夏鹏、李宪龙、张涛 获奖情况&#xff1a;…

有一种浪漫,叫接触Linux

大家好&#xff0c;我是五月。 嵌入式开发 嵌入式开发产品必须依赖硬件和软件。 硬件一般使用51单片机&#xff0c;STM32、ARM&#xff0c;做成的产品以平板&#xff0c;手机&#xff0c;智能机器人&#xff0c;智能小车居多。 软件用的当然是以linux系统为蓝本&#xff0c…

7.5 Windows驱动开发:监控Register注册表回调

在笔者前一篇文章《内核枚举Registry注册表回调》中实现了对注册表的枚举&#xff0c;本章将实现对注册表的监控&#xff0c;不同于32位系统在64位系统中&#xff0c;微软为我们提供了两个针对注册表的专用内核监控函数&#xff0c;通过这两个函数可以在不劫持内核API的前提下实…