Kotlin学习之集合

news2024/11/25 18:55:54

原文链接 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

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

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

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

相关文章

Adversarial Attack and Defense on Graph Data: A Survey(2022 IEEE Trans)

Adversarial Attack and Defense on Graph Data: A Survey----《图数据的对抗性攻击和防御&#xff1a;综述》 图对抗攻击论文数据库&#xff1a; https://github.com/safe-graph/graph-adversarial-learning-literature 摘要 深度神经网络&#xff08;DNN&#xff09;已广泛应…

360压缩安装一半不动了?一分钟解决!

360压缩软件是我们常用的压缩软件&#xff0c;但是常常会遇到压缩安装到一半停止的情况&#xff0c;下面提供了一些可能的原因和解决办法&#xff0c;大家可以进行尝试~ 方法一&#xff1a;关闭防火墙和杀毒软件 有时候&#xff0c;防火墙和杀毒软件可能会阻止360压缩的安装过…

计算机组成原理——存储器(主存容量扩展)

对于字扩展与位扩展的解释&#xff1a; 计算机原理中的字&#xff0c;位扩展&#xff0c;都给老子进来学&#xff0c;看不懂算我输&#xff01; 如果主存的容量无法满足 CPU 的需求&#xff0c;可以通过存储器扩展来解决&#xff0c;扩展的方式有两种&#xff1a; 主存的位数…

java学习part17

110-面向对象(高级)-关键字final的使用及真题_哔哩哔哩_bilibili 1.概念 tips&#xff1a;java里有const关键字&#xff0c;但是用于保留字&#xff0c;不会使用&#xff0c;目前没有意义。 final变量没有默认赋值&#xff0c;只能在以下三个地方赋值&#xff0c;且只能赋值一…

『VUE3后台—大事件管理系统』

项目地址:https://gitee.com/csheng-gitee/vue3-big-event-admin 技术栈:VUE3 + Pinia + Pnpm(本项目暂不用 typescript) 一、前期准备工作 1、创建项目 npm install -g pnpm pnpm create vue2、ESLint 配置 (1) 禁用 prettier 插件,下载 ESLint 插件;(2) 在 vscode 的…

好题分享(2023.11.19——2023.11.25)

目录 ​编辑 前情回顾&#xff1a; 前言&#xff1a; 认识循环队列&#xff1a; 实现循环队列的思路&#xff1a; 题目&#xff1a;《设计循环队列》 1.判满和判空&#xff1a; 2.添加数据和删除 3.计算循环队列的数据个数 4.返回对队尾元素 总结&#xff1a; 前情回…

内部类, Comparable接口, Comparator接口, Cloneable接口 ---java

目录 一. 内部类 1.1 静态内部类 1.2 实例内部类 1.3匿名内部类 二. 接口的使用实例 2.1 Comparable接口 2.2 Comparator接口 ---比较器 2.3 Cloneable接口 深拷贝浅拷贝 一. 内部类 当一个事物的内部&#xff0c;还有一个部分需要一个完整的结构进行描述&#xff0…

从零开始学Go web——第一天

文章目录 从零开始学Go web——第一天一、Go与web应用简介1.1 Go的可扩展性1.2 Go的模块化1.3 Go的可维护1.4 Go的高性能 二、web应用2.1 工作原理2.2 各个组成部分2.2.1 处理器2.2.2 模板引擎 三、HTTP简介四、HTTP请求4.1 请求的文本数据4.2 请求方法4.2.1 请求方法类型4.2.2…

C语言:输出所有“水仙花数”。“水仙花数”是指一个3位数,其各位数字的立方和等于该数本身,如153=1^3 +5^3+3^3

分析&#xff1a; 在主函数 main 中&#xff0c;程序首先定义四个整型变量 m、a、b 和 c&#xff0c;并用于计算和判断水仙花数。然后使用 printf 函数输出提示信息。 接下来&#xff0c;程序使用 for 循环结构&#xff0c;从 100 到 999 遍历所有三位数。对于每个遍历到的数 m…

C#常见的设计模式-创建型模式

引言 在软件开发过程中&#xff0c;设计模式是一种被广泛采用的思想和实践&#xff0c;可以提供一种标准化的解决方案&#xff0c;以解决特定问题。设计模式分为三种类型&#xff1a;创建型模式、结构型模式和行为型模式。本篇文章将重点介绍C#中常见的创建型模式。 目录 引言…

python实现自动刷平台学时

背景 前一阵子有个朋友让我帮给小忙&#xff0c;因为他每学期都要看视频刷学时&#xff0c;一门平均需要刷500分钟&#xff0c;一学期有3-4门需要刷的。 如果是手动刷的话&#xff0c;比较麻烦&#xff0c;能否帮他做成自动化的。搞成功的话请我吃饭。为了这顿饭&#xff0c;咱…

Elasticsearch:什么是非结构化数据?

非结构化数据定义 非结构化数据是指未按照设计的模型或结构组织的数据。 非结构化数据通常被归类为定性数据&#xff0c;可以是人类或机器生成的。 非结构化数据是最丰富的可用数据类型&#xff0c;经过分析后&#xff0c;可用于指导业务决策并在许多其他用例中实现业务目标。…

正则表达式和awk

目录 一、正则表达式 1.正则表达式基本介绍 2.正则表达式分类 3.基本正则表达式分类 4.代表字符 5.表示次数 6.位置锚定 7.分组或其他 8.扩展正则表达式 二、awk 1.语法 2.选项 3.基础用法 4.内置变量 5.条件判断 6.数组 总结&#xff1a;本章主要介绍了正则表…

【C++】map与set

​&#x1f47b;内容专栏&#xff1a;C/C编程 &#x1f428;本文概括&#xff1a;关联式容器的介绍、set、multiset、map、multimap。 &#x1f43c;本文作者&#xff1a;阿四啊 &#x1f438;发布时间&#xff1a;2023.11.27 一、关联式容器的介绍 在之前C的学习之中&#xf…

STM32入门--看门狗

一、独立看门狗简介 STM32F10xxx内置两个看门狗&#xff0c;提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备(独立看门狗和窗口看门狗)可用来检测和解决由软件错误引起的故障&#xff1b;当计数器达到给定的超时值时&#xff0c;触发一个中断(仅适用于窗口型看…

【vue】a-table的斑马纹以及hover样式的修改:

文章目录 一、效果&#xff1a;二、实现&#xff08;以jeecg为例&#xff09;&#xff1a; 一、效果&#xff1a; 二、实现&#xff08;以jeecg为例&#xff09;&#xff1a; // 设置基数行样式 // .ant-table-tbody tr:nth-child(n) { // color: #fff; // }// hover时候每行…

如何使用 Java 在Excel中创建下拉列表

下拉列表&#xff08;下拉框&#xff09;可以确保用户仅从预先给定的选项中进行选择&#xff0c;这样不仅能减少数据输入错误&#xff0c;还能节省时间提高效率。在MS Excel中&#xff0c;我们可以通过 “数据验证” 提供的选项来创建下拉列表&#xff0c;但如果要在Java程序中…

Android应用程序开发实战篇----期末总结1

项目1&#xff08;了解移动电子商务开发&#xff09; 1,任务一&#xff1a;了解移动电子商务 移动电子商务&#xff1a;利用无线终端进行的电子商务活动。 移动电子商务的特点&#xff1a;方便&#xff0c;摆脱时空性&#xff0c;安全&#xff0c;潜在用户规模大&#xff0c;…

loadrunner-关联

loadrunner-关联 文章目录 关联自动关联手动关联手写脚本&#xff0c;关联登录token 关联 关联的作用是将服务器返回的数据保存为参数&#xff0c;后续接口中会用到该参数&#xff0c;当服务器数据发生变更时&#xff0c;脚本中的参数值也同时进行更新。 当脚本中需要服务器返…

Open Feign 源码解析(二) --- 如何发送http请求

Open Feign 源码解析二 如何发送http请求&#xff1f; 如何组件化&#xff1f; 定义接口 public interface Client {Response execute(Request request, Options options) throws IOException; }是否存在已有的方案&#xff1f; 1&#xff09;rest template http client o…