kotlin将对象转换为map_Kotlin 集合框架:常用集合工具函数(Map 部分)

kotlin.collections.Maps.kt 文件定义了许多针对 Map 接口的工具函数,其中大多数是涉及函数式编程的高阶函数,我们在这里先不讲,等到集合框架结束后进入高阶函数时再讲。今天只讲几个简单的函数。

Pair 类和 to() 函数

Map 接口表示一种“键 -> 值”的数据结构,一个键对应一个值。但在具体实现中,Map 并没有维护键和值两个结构,而是一个个 Entry 对象,每个 Entry 对象表示一个键与值的对应关系,它有 3 个属性:key、value 和 hash,因为 hash 只与 key 有关,所以可以视为只有两个属性:key 和 value。

Kotlin 为简化 Map 的创建,定义了一个新类:Pair,它相当于简化版的 Map.Entry 类:

// kotlin.Tuple.ktdata class Pair(

val first: A,

val second: B

) : Serializable {

override fun toString() = "($first, $second)"

}

嗯,我们复习一下数据类,请问这个 Pair 类封装了哪些函数呢?

答案是 getFirst()、getSecond()、component1()、component2()、copy()、hashCode()、equals() 函数。

这里的 first 相当于 key、second 相当于 value,hashCode() 充当了 hash 属性。

有了 Pair 类还不够,Kotlin 还定义了一个 to 函数来创建 Pair 对象:

// kotlin.Tuple.ktinfix fun A.to(that: B): Pair = Pair(this, that)

这是一个用 infix 修饰的中缀函数,也是一个 A 类对象的扩展函数,它接受一个 B 类的参数,使用被扩展的 A 类对象和作为参数的 B 类对象创建一个 Pair 对象。于是我们就能这样写了:

val p1 = 1 to "Hello"

// 等价于 val p1 = 1.to("Hello")val p2 = p1 to "World"

// p1: Pair// p2: Pair, String>

mapOf() 与 mutableMapOf() 函数

与 List 和 Set 相似,Kotlin 的 Map 接口也提供了生成不可变 Map 的 mapOf() 函数和生成可变 Map 的 mutableMapOf() 函数,不过与前两者不同的是,Map 接口的两个函数 只接受 Pair 对象作为参数:

inline fun mapOf(): Map = emptyMap()

fun mapOf(pair: Pair): Map =

java.util.Collections.singletonMap(pair.first, pair.second)

fun mapOf(vararg pairs: Pair): Map =

if (pairs.size > 0) linkedMapOf(*pairs) else emptyMap()

inline fun mutableMapOf(): MutableMap = LinkedHashMap()

fun mutableMapOf(vararg pairs: Pair): MutableMap =

LinkedHashMap(mapCapacity(pairs.size)).apply { putAll(pairs) }

可以注意这几个细节:mapOf() 和 mutableMapOf() 在元素数大于 1 时,都采用 LinkedHashMap 的实现方式,这与 setOf() 和 mutableSetOf() 函数采用 LinkedHashSet 的实现是相似的。此外,因为 LinkedHashSet 只是对 LinkedHashMap 的简单包装,可以认为这四个函数都采用了相似的实现方式。

linkedMapOf(*pairs) 是什么写法?别以为这是 C 语言的指针呀,这叫 展开操作符,一般来说,我们给 vararg 函数传参数时,只能一个一个地传,如果想把一个数组传给 vararg 参数,可以在数组前面加个 *,告诉编译器:“我不是把数组对象作为参数,而是把数组里的每个元素作为参数”,可以这样写:

val array = intArrayOf(1, 2, 3)

val list = listOf(0, *array, 4, 5)

// list: List = [0, 1, 2, 3, 4, 5]

这里用到了改进的 putAll() 函数,下面会讲到。

hashMapOf() 与 linkedMapOf() 函数

与 List 和 Set 接口几个具体实现类函数相似,hashMapOf() 和 LinkedMapOf() 函数创建的都是 可变 Map:

inline fun hashMapOf(): HashMap = HashMap()

fun hashMapOf(vararg pairs: Pair): HashMap =

HashMap(mapCapacity(pairs.size)).apply { putAll(pairs) }

inline fun linkedMapOf(): LinkedHashMap = LinkedHashMap()

fun linkedMapOf(vararg pairs: Pair): LinkedHashMap =

LinkedHashMap(mapCapacity(pairs.size)).apply { putAll(pairs) }

解构函数

我们之前讲到了,所谓解构函数就是用 operator 关键字修饰的 componentN() 函数,这里的 N 是从 1 到 5 的整数。Maps.kt 中定义了两个解构函数:

inline operator fun Map.Entry.component1(): K = key

inline operator fun Map.Entry.component2(): V = value

它们都是 Map.Entry 的扩展函数,分别返回这个 Entry 的键和值,常用来遍历 Map 的键和值:

val map = mapOf(1 to 2, 3 to 4)

for((key, value) in map) {

println("$key -> $value")

}

// 1 -> 2// 3 -> 4

这个 for 循环会遍历 map 的每一个 Entry,调用解构函数分别把 Entry 的键和值赋给临时变量 key 和 value,然后用 key 和 value 执行我们定义的循环体。

plus() 与 minus() 函数

Map.kt 重载了操作符 + 和 -,方便我们增删元素。因为重载函数实在太多,这里就不列出来了,总结几个点吧:所有 plus() 和 minus() 函数都是 不可变 的 Map 的扩展函数,所以每次调用 plus() 或 minus() 函数都会产生一个新的 Map,这在 Map 内元素很多时可能会产生性能问题。

plus() 和 minus() 函数有以下几种参数不同的重载形式:Array>:Pair 数组;

Iterable>:Pair 集合;

Pair:单个 Pair 对象;

Sequence>:Pair 序列(Kotlin 添加的新集合形式)

Map:另一个 Map;

对于 MutableMap,Maps.kt 重载了 +=(plusAssign() 函数)和 -=(minusAssign() 函数)操作符,分别相当于调用 put() / putAll() 函数和 remove() / removeAll() 函数:

val mutableMap = mutableMapOf(1 to 2, 3 to 4)

mutableMap += arrayOf(1 to 2, 5 to 6)

// mutableMap = [1->2, 3->4, 5->6]mutableMap -= 3

// mutableMap = [1->2, 5->6]

toMap() 函数

Maps.kt 还提供了一系列 toMap() 函数,用来将其它数据形式的 Pair 对象转换为 可变 的 Map,包括下面两套重载形式:支持 Array>、Iterable>、Sequence> 和 Map 四种数据结构转换为 Map;

支持无参和一个 destination 参数两种形式,前者直接将转换得到的 Map 赋给自身,后者则会把转换成的 Map 赋给 destination。

改进的 putAll() 函数

Maps.kt 给 MutableMap 重载了三个新的 putAll() 函数,它们分别接受 Array>、Iterable> 和 Sequence> 对象。

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

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

相关文章

Oracle/MySQL/Java数据类型对应表

文章目录数据类型对照表MySQL 的 int、bigint、mediumint、smallint、tinyint 的对比关于 MySQL 整型显示位数的问题关于 MySQL 的 timestamp关于 JDBC 类型数据类型对照表 MysqlOracleJavaBIGINTNUMBER(19,0)java.lang.LongBITRAWbyte[]BLOBBLOB RAWbyte[]CHARCHARjava.lang.…

java10个基础错误_我们处理了10亿个Java记录的错误-这是导致97%的错误的原因

java10个基础错误97%的记录错误是由10个唯一错误引起的 在2016年,一件事在30年内没有改变。 开发和运营团队仍依靠日志文件对应用程序问题进行故障排除。 由于某些未知原因,我们隐式信任日志文件,因为我们认为事实隐藏在其中。 如…

MySQL的索引学习

文章目录索引自动创建索引手动创建索引删除索引使用索引单列索引PRIMARYNORMALUNIQUEFULLTEXT组合索引(复合索引/联合索引)索引不足之处索引使用注意事项索引方式 Hash 和 BTree 比较删除索引索引 数据库的索引就像一本书的目录,能够加快数据…

aptx与ldac音质区别_蓝牙协议LDAC和aptx的区别?

LDAC技术的功能介绍LDAC是索尼研发的一种无线音频编码技术,它最早在2015年的CES消费电子设备大展上亮相。在当时,索尼表示比起标准的蓝牙编码、压缩系统,LDAC技术要高效三倍之多。这样一来,那些高解析度的音频文件在进行无线传输的…

【音视频安卓开发 (九)】使用AudioRecord录制PCM音频

1.需要添加权限 <uses-permission android:name"android.permission.CAMERA" /><uses-permission android:name"android.permission.FLASHLIGHT" /><uses-permission android:name"android.permission.CAMERA" /><uses-per…

结果集 tostring_关于避免对toString()结果进行解析或基于逻辑的美德

结果集 tostring使用Java或我使用过的其他编程语言&#xff0c;我发现有时候可以用该语言完成某些事情&#xff0c;但通常不应该这样做。 通常&#xff0c;这些误用语言似乎无害&#xff0c;当开发人员首次使用它们时可能是有益的&#xff0c;但后来同一位开发人员或另一位开发…

3制造数据集_基于MBD的产品设计制造技术研究

本篇节选自论文《基于MBD的产品设计制造技术研究》&#xff0c;发表于《中国电子科学研究院学报》第8卷第6期&#xff0c;作者为中国电子科技集团公司第14研究所专家朱建军。本文经授权转载自公众号学术plus&#xff0c;版权归原作者所有。作者&#xff1a;中国电子科技集团公司…

JSP文件如何转换成Java文件?

文章目录jsp 文件如何转换成 java 文件jsp 何时开始编译jsp 编译后的文件存储目录jsp 文件如何转换成 java 文件 html ----> service(),使用 out.write()输出。 java代码片段 <% %> ----> service(),照…

【WebRTC---源码篇】(九)媒体协商

1.媒体协商的过程 2. 重要的接口类 3.时序图 4.几个关键点 5.code if (InitializePeerConnection()) {peer_id_ = peer_id;//参数1:观察者,创建成功后回调OnSuccess//参数2:消息类型,自动推导peer_connection_->CreateOffer(this, webrtc::PeerConnectionInterface::RTCOff…

jpa 使用jdbc_在JPA和JDBC中使用存储过程。 嗯,只要使用jOOQ

jpa 使用jdbcJava杂志的当前版本由Josh Juneau撰写了有关JDBC和JPA的大数据最佳实践的文章&#xff1a; http : //www.javamagazine.mozaicreader.com/MayJune2016 本文介绍了如何在JDBC中使用存储过程&#xff08;不幸的是&#xff0c;请注意如何关闭资源。即使在Java Magazi…

JSP文件中Java代码的几种形式(JSP脚本)

文章目录第一种形式&#xff08;Java 代码片段&#xff09;第二种形式&#xff08;JSP 表达式&#xff09;第三种形式&#xff08;JSP 声明&#xff09;第四种形式&#xff08;JSP 指令&#xff09;第一种形式&#xff08;Java 代码片段&#xff09; 原样复制到 service() 方法…

【WebRTC---源码篇】(七)NACK的处理流程

NACK调用栈 从分发器接收Packet包 void RtpVideoStreamReceiver::ReceivePacket(const RtpPacketReceived& packet) {if (packet.payload_size() == 0) {// Padding or keep-alive packet.// TODO(nisse): Could drop empty packets earlier, but need to figure out how…

java实现资源监视器_实现Java监视的12个步骤程序存在缺陷

java实现资源监视器Java监视的当前状态最大的问题是什么&#xff1f; 生产中的错误很像喝醉的短信。 您只有在事情已经发生之后才意识到出了点问题。 发短信日志通常比应用程序错误日志更有趣&#xff0c;但是……两者可能同样难以修复。 在本文中&#xff0c;我们将执行一个…

QT之QML布局相关总结

使用QML有助于提高界面编写效率&#xff0c;对付界面开发来说&#xff0c;页面如何布局是一个绕不开的点&#xff0c;本文总结一下QML中常用的一些和布局相关的内容。 目录 1.手动定位 2.坐标绑定定位 3.锚定位 4.布局定位器 5.布局管理器 6.其他布局相关 6.1 弹簧功能…

bpmn2 vue 设计器_vue项目中使用bpmn-基础篇

后退前进下载style"display: inline-block;":file-list"fileList"class"upload-demo"action"":auto-upload"false":show-file-list"false":http-request"httpRequest":on-change"handleOnchangeFi…

JSP的隐含对象/隐藏对象/内置对象介绍

文章目录outJspWriter 和 PrintWriter 的区别requestresponsesessionapplicationexceptionconfigpageContextpageContext 的作用绑订数据获得其它几个隐含对象page四个 JSP 域对象访问范围比较out out 对象是 javax.servlet.jsp.JspWriter 类的实例&#xff0c;用来在 respons…

hystrix应用 博客_使用Hystrix DSL创建弹性骆驼应用程序

hystrix应用 博客Apache Camel是一个成熟的集成库&#xff08;到现在已有9年的历史了&#xff09;&#xff0c;它实现了Enterprise Integration Patterns一书中的所有模式。 但是Camel不仅是EIP实现库&#xff0c;它还是一个不断发展&#xff0c;添加新模式并适应行业变化的现代…

notebook打开外部文件_CAD外部参照真是个好东西!

好课推荐&#xff1a;零基础CAD&#xff1a;点我CAD室内&#xff1a;点我 周站长CAD&#xff1a;点我CAD机械&#xff1a;点我 Bim教程&#xff1a;点我CAD建筑&#xff1a;点我CAD三维&#xff1a;点我全屋定制&#xff1a;点我 ps教程&#xff1a;点我苹果版CAD:点我 3dmax教…

JSP动作元素/活动元素

文章目录jsp:forwardjsp:includejsp:paramjsp:useBeanjsp:setPropertyjsp:setProperty name"" property"" value""jsp:setProperty name"" property"" param""jsp:setProperty name"" property"*&…