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

本文介绍了Kotlin中用于创建和操作Map的实用工具函数,包括`Pair`类、`to()`函数、`mapOf()`、`mutableMapOf()`、`hashMapOf()`、`linkedMapOf()`、解构函数、`plus()`、`minus()`以及`toMap()`等。这些函数简化了Map的创建和操作,提高了代码的简洁性和效率。
摘要由CSDN通过智能技术生成

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> 对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值