Kotlin集合接口

Kotlin 集合概述

Kotlin 集合提供了对数据进行各种操作的便捷方式。它们实现了接口,因此可以操作不同类型的数据。例如,你可以编写一个函数,同时打印 SetList 的所有元素。我们来看看这是如何实现的。


Iterable 接口

我们已经知道,Kotlin 中有两个通用接口:IterableMutableIterable,它们提供了一系列用于处理元素序列的方法。

继承自 Iterable 的类拥有一组通用方法,例如:

  • iterator()

  • forEach()

  • contains()

  • count()

  • drop()

  • filter() 等。

MutableIterable 除了拥有 Iterable 的方法外,还支持迭代时移除元素的方法,例如:

  • remove()

  • removeAll()

值得注意的是,虽然 drop()remove() 都可以“移除”元素,但它们的行为不同:

  • drop() 返回的是一个新的集合对象

  • remove()直接修改原集合对象(前提是集合是可变的)。

还要注意:你只能使用同一个 iterator 对象遍历一次集合,如果想再遍历一次,就必须重新创建一个新的 iterator()

当然你也可以使用 for 循环或者 forEach() 来迭代集合。


Collection 接口结构

我们来看看 Kotlin 集合之间的继承关系:

  • Iterable<T>Collection<T>List<T>Set<T>

  • MutableIterable<T>MutableCollection<T>MutableList<T>MutableSet<T>

其中:

  • Collection<T> 是不可变集合的根接口,支持 sizeget()find()filter()count() 等方法。

  • MutableCollection<T> 是可变集合的根接口,支持 add()remove()drop()addAll() 等方法。

注意:虽然我们通常也将 Map 称作集合,但它并不继承CollectionIterable,因为它存储的是键值对而不是单个元素,所以它有自己独特的方法集合。


使用 Collection 接口举例

你可以通过三种方式遍历集合:

fun printAll(strings: Collection<String>) {for (str in strings) print("$str ")
}fun printAll(songs: Collection<String>) {songs.forEach { print("$it ") }
}fun printAll(songs: Collection<String>) {val songsIterator = songs.iterator()while (songsIterator.hasNext()) {print("${songsIterator.next()} ")}
}

示例:

val listOfSongs = listOf("Creep", "Idioteque", "Street Spirit", "Paranoid Android")
printAll(listOfSongs)
// 输出:Creep Idioteque Street Spirit Paranoid Android

所有集合都有一些通用的方法:

  • count():返回满足条件的元素数量。

  • drop():返回一个新的列表,其中不包含前 n 个元素。

  • containsAll():检查集合是否包含另一个集合中的所有元素,并返回 true 或 false。
    常用方法示例:

fun countElements(strings: Collection<String>) = strings.count { it.matches("\\w+".toRegex()) }fun dropElements(songs: Collection<String>) = songs.drop(2).toSet()fun compareCollections(old: Collection<String>, new: Collection<String>) = old.containsAll(new)val setOfSongs = setOf("Creep", "Idioteque", "Street Spirit", "Paranoid Android")
val listOfSongs = listOf("Creep", "Idioteque", "Street Spirit", "Paranoid Android")println(countElements(setOfSongs)) // 输出:2
println(dropElements(listOfSongs)) // 输出:[Street Spirit, Paranoid Android]
println(compareCollections(listOfSongs, setOfSongs)) // 输出:true

更多集合操作方法

  • joinToString()将集合作为带有特定分隔符的字符串返回。

  • find()返回符合模式的第一个元素。

  • filter()返回List满足条件的元素。

  • minus()返回不包含条件中指定的元素的集合。

  • random()返回集合中的一个随机元素。
    一些例子:

fun convertToString(strings: Collection<String>) = strings.joinToString(" | ")fun findElement(strings: Collection<String>) = strings.find { it.contains("I") }fun filterElements(strings: Collection<String>) = strings.filter { it.contains("t") }fun returnRandomElement(strings: Collection<String>) = strings.random()fun decreaseCollection(strings: Collection<String>) = strings.minus("Creep")

示例:

val listOfSongs = listOf("Creep", "Idioteque", "Street Spirit", "Paranoid Android")
val setOfSongs = setOf("Creep", "Idioteque", "Street Spirit", "Paranoid Android")println(convertToString(listOfSongs)) // Creep | Idioteque | Street Spirit | Paranoid Android
println(findElement(setOfSongs))     // Idioteque
println(filterElements(listOfSongs)) // [Idioteque, Street Spirit]
println(returnRandomElement(setOfSongs)) // 可能输出任意一个元素
println(decreaseCollection(setOfSongs))  // [Idioteque, Street Spirit, Paranoid Android]

注意:drop()minus() 都不会修改原集合,而是返回一个新的集合对象。


MutableCollection 可变集合

MutableCollection 可以使用 Collection 的所有方法,还支持如下修改原集合的方法:

  • addAll():添加一整个集合。

  • add():添加单个元素。

  • clear():清空集合。

  • remove():移除元素的第一个出现位置。

fun addCollection(old: MutableCollection<String>, new: Collection<String>) {old.addAll(new)
}fun addNewElement(old: MutableCollection<String>) {old.add("Spectre")
}fun clearCollection(old: MutableCollection<String>) {old.clear()
}fun removeElement(old: MutableCollection<String>): Boolean {return old.remove("Creep")
}

示例:

val oldSongs = mutableSetOf("Creep", "Street Spirit")
val newSongs = listOf("Creep", "Street Spirit", "Paranoid Android")clearCollection(oldSongs)
println(oldSongs) // []addCollection(oldSongs, newSongs)
println(oldSongs) // [Creep, Street Spirit, Paranoid Android]addNewElement(oldSongs)
println(oldSongs) // [Creep, Street Spirit, Paranoid Android, Spectre]removeElement(oldSongs)
println(oldSongs) // [Street Spirit, Paranoid Android, Spectre]
println(removeElement(oldSongs)) // false,因为没有 "Creep" 了

retainAll()

retainAll() 方法会让集合只保留在另一个集合中也存在的元素:

fun retainAllFromCollection(old: MutableCollection<String>, new: Collection<String>) {old.retainAll(new)
}val oldSongs = mutableSetOf("Creep", "Street Spirit", "Paranoid Android")
val newSongs = listOf("Spectre", "Street Spirit")retainAllFromCollection(oldSongs, newSongs)
println(oldSongs) // [Street Spirit]

函数与集合的关系

你可以使用集合的接口类型(如 CollectionList)作为函数的参数,以创建更通用的处理函数。例如:

fun processNumbers(list: List<Number>) {list.forEach { print("$it ") }
}val numbers1 = listOf(0, 12, 10)
val numbers2 = listOf(0.0, 12.0, 10.0)
val numbers3 = listOf(423324534536356, 4L, 56L)processNumbers(numbers1) // 0 12 10
processNumbers(numbers2) // 0.0 12.0 10.0
processNumbers(numbers3) // 423324534536356 4 56

但如果你尝试在 Number 类型上做加法,会出错:

fun processNumbers(list: List<Number>) {list.forEach { print(it + 1) } // ❌ 报错:未解析的引用
}

因为 Number 是抽象类,不支持加法。你可以先转换类型:

fun processNumbers(list: List<Number>) {list.forEach { print("${it.toChar()} ") }
}val numbers1 = listOf(41, 42, 43)
processNumbers(numbers1) // ) * +

总结

  • Kotlin 中集合是接口,可以通用于多种集合类型。
  • CollectionMutableCollection 提供了许多通用操作方法。
  • Map 虽然被称为集合,但并不继承自 Collection。可以编写通用函数处理 SetListMutableSetMutableList 等集合类型。
  • drop()minus() 不改变原集合,而 remove()add() 会修改原集合(前提是集合是可变的)。

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

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

相关文章

Git 常用操作与注意事项全攻略

1. 基本配置 git config --global user.name "你的名字" git config --global user.email "你的邮箱" git config --list # 查看当前配置建议全局配置用户名和邮箱&#xff0c;否则提交记录可能不规范2.仓库操作 初始化本地仓库 git init只在新建项目时使…

STM32-第五节-TIM定时器-1(定时器中断)

一、定时器原理&#xff1a;1.介绍&#xff1a;对指定输入时钟进行计数&#xff0c;并在计数值达到设定值时触发中断。分类&#xff1a;基本定时器&#xff0c;通用定时器&#xff0c;高级定时器频率&#xff1a;72MHZ2.框图&#xff1a; &#xff08;1&#xff09;基本定时器&…

【图像处理基石】什么是色盲仿真技术?

色盲仿真概述 色盲仿真是一种将正常色彩图像转换为色盲患者感知效果的技术。人类常见的色盲类型包括&#xff1a; 红色盲&#xff08;Protanopia&#xff09;&#xff1a;无法感知红色绿色盲&#xff08;Deuteranopia&#xff09;&#xff1a;无法感知绿色蓝黄色盲&#xff08;…

九、官方人格提示词汇总(中-3)

“参谋代写计划”功能输出欣赏&#xff0c;规则&#xff1a; 本部分统一使用 Gemini 2.5 Pro API。该 API 下的输出质量基本达到我的要求&#xff0c;已具备实用价值。严格等级均为“权衡有度&#xff08;L3&#xff09;”&#xff0c;创造力等级均为“趋势捕手&#xff08;L3…

华为MateBook D 16 SE版 2024款 12代酷睿版i5集显(MCLF-XX,MCLF-16)原厂OEM预装Win11系统

适用型号&#xff1a;MCLF-XX,MCLF-16链接&#xff1a;https://pan.baidu.com/s/1OkvUqZMdCSF98YtQfWAYXw?pwdq2gh 提取码&#xff1a;q2gh 华为开箱状态出厂Windows11系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、华为电脑…

Python自动化:每日销售数据可视化

这是手动执行sql分组查出的Linda奶茶店每日的销售数据,那么能否图形化展示方便对比近一个月每日的销售趋势呢。如果是做在网站里,前端可以集成echart或highchart生成柱状图或线状图。如果需要每天定时推送这些数据到邮箱或其他消息通知渠道,第一步肯定是需要先生成图片到服务…

scrapy项目开发流程

1.创建项目&#xff1a;scrapy startproject mySpider2.生成一个爬虫&#xff1a;scrapy genspider itcast itcast.cn3.提取数据&#xff1a;根据网站结构在spider中实现数据采集相关内容4.保存数据使用pipeline进行数据后续处理和保存1.创建项目items.py-->自己预计需要爬取…

堆排序以及其插入删除

堆排序首先介绍一下堆排序属于选择排序的一种类型。其次就是他有点依赖于顺序存储树判断其孩子以及父节点的概念&#xff0c;接下来复习一下。堆分为大根堆和小根堆① 若满⾜&#xff1a;L(i)≥L(2i)且L(i)≥L(2i1) &#xff08;1 ≤ i ≤n/2 &#xff09;—— ⼤根堆&#xff…

Spring Boot项目结构解析:构建高效、清晰的代码框架

在当今的软件开发领域&#xff0c;Spring Boot因其简洁性和强大的功能而备受青睐。它不仅简化了Spring框架的配置&#xff0c;还提供了一套高效的项目开发模式。本文将深入探讨Spring Boot项目结构中的关键组件&#xff0c;包括PO、Query、VO、Config等&#xff0c;旨在帮助开发…

多客户端 - 服务器结构-实操

实现2个客户端之间互相聊天 要求&#xff1a; 1、服务器使用 select 模型实现接受多个客户端连接&#xff0c;以及转发消息 2、客户端要求&#xff1a;使用 poll 模型解决 技能够 read 读取服务器发来的消息&#xff0c;又能够scanf读取键盘输入的信息 3、客户端服务器不允许开…

iOS高级开发工程师面试——Objective-C 语言特性

iOS高级开发工程师面试——Objective-C 语言特性 一、多态二、继承三、代理(Delegate)1. 代理为什么用 weak 修饰呢?block和代理的区别?四、通知(NSNotificationCenter)五、KVC (Key-value Coding)六、属性七、`@property` [ˈprɒpəti]的本质是什么?ivar 、 setter …

MMpretrain 中的 LinearClsHead 结构与优化

LinearClsHead 结构与优化 一、LinearClsHead 核心结构 在 MMPretrain 中&#xff0c;LinearClsHead 是一个简洁高效的分类头&#xff0c;其核心结构如下&#xff1a; class LinearClsHead(BaseModule):def __init__(self,num_classes, # 类别数量in_channels, # 输入…

Spring 学习笔记

1.Spring AOP 怎么实现的AOP 即面向切面编程&#xff0c;是通过代理实现的&#xff0c;主要分为静态代理和动态代理&#xff0c;静态代理就是在程序运行前就已经指定并声明了代理类和增强逻辑&#xff0c;运行时就已经被编译为字节码文件了&#xff0c;而动态代理则是在运行过程…

【CVPR2024】计算机视觉|InceptionNeXt:速度与精度齐飞的CNN架构

论文地址&#xff1a;http://arxiv.org/pdf/2303.16900v3 代码地址&#xff1a;https://github.com/sail-sg/inceptionnext 关注UP CV缝合怪&#xff0c;分享最计算机视觉新即插即用模块&#xff0c;并提供配套的论文资料与代码。 https://space.bilibili.com/473764881 摘要…

7.15 窗口函数 | 二分 | 位运算 | 字符串dp

lc3316. 字符串dpdp多开一行一列后&#xff0c;注意原字符串下标映射dp[n][m] &#xff08; n 是source长度&#xff0c; m 是pattern长度&#xff09;两重循环填表for i 1-nfor j 0-m三种状态转移1.不选 dp i jdp i-1 j2.不选if tag, dp[i][j]3.if(s ip j) 选&#xff0c;dp i…

Spring原理揭秘--初识AOP

我们知道软件开发一直在追求高效&#xff0c;易维护&#xff0c;易扩展的特性方式。在面向过程编程到面向对象编程的历程中&#xff0c;程序的开发有了非常大的进步。但是oop的方式缺依然存在着一些缺点。oop的方式可以将业务进行很好的分解和封装使其模块化&#xff0c;但是却…

Provider模式:软件架构中的“供应商“设计哲学

文章目录Provider模式&#xff1a;软件架构中的“供应商“设计哲学什么是Provider模式&#xff1f;经典应用场景1. 配置管理Provider2. 数据访问Provider4. 消息队列ProviderProvider模式的优势1. 解耦合实际项目中的应用Provider模式的最佳实践1. 命名约定2. 接口设计原则3. 错…

LTspic下载,帮助及演示电路

1.下载 LTspice是一款强大高效的免费SPICE仿真器软件、原理图采集和波形观测器&#xff0c;为改善模拟电路的仿真提供增强功能和模型。其原理图捕获图形界面使您能够探测原理图并生成仿真结果&#xff0c;这些结果可以通过内置波形查看器进一步观察分析。 链接&#xff1a; …

位置编码/绝对位置编码/相对位置编码/Rope原理+公式详细推导及代码实现

文章目录1. 位置编码概述1.1 为什么需要位置编码&#xff1f;2. 绝对位置编码 (Absolute Position Encoding)2.1 原理2.2 数学公式2.3 代码实现2.4 代码与公式的对应关系2.5 特性与优势2.6 可学习的绝对位置编码3. 相对位置编码 (Relative Position Encoding)3.1 原理3.2 数学公…

网络安全初级第一次作业

一&#xff0c;docker搭建和挂载vpm 1.安装 Docker apt-get install docker.io docker-compose 2.创建文件 mkdir /etc/docker.service.d vim /etc/docker.service.d/http-proxy.conf 3.改写文件配置 [Service] Environment"HTTP_PROXYhttp://192.168.10.103:7890…