Kotlin Maps:五个基本函数

2021-12-24 15:00:39 浏览数 (1)

周末学习kotlin的时候顺便对Map做了总结,特此记录下来

科特林你好世界

映射,也称为?关联数组,是任何编程语言中的核心数据类型。列表和映射可能是最常见的数据类型。因此,熟悉它们是学习一门新语言的必要步骤。

Kotlin对开箱即用的maps提供全面支持。首先,您可以在本地使用Java 的集合框架,这是业内最知名且久经考验的框架之一。此外,Kotlin 添加了一些额外的功能,使maps使用起来更加方便。

在这篇文章中,我谈论的是maps的基础知识。我将向您展示处理maps时最常用的函数。

Kotlin 中maps的用途

在使用maps之前了解什么是maps。本质上,映射是键值对的集合。关键是标识符。您可以使用它来查找集合中的特定元素。该值是您要存储的数据,它与一个键相关联。

本质上,映射是键值对的集合。

数据类型的实现是?数据结构。maps的主要实现有两种:

  • ?哈希表:它使用哈希函数来计算每个键的索引。这些对基于该索引进入一个桶数组。只要散列函数均匀分配密钥,性能就是线性的。
  • ?搜索树:它使用树结构来存储键。性能不如哈希表。但是,它会根据键的自然顺序对键进行排序。

通常,除非您需要按顺序迭代键,否则您将使用哈希表。

对于本文,实现不相关,因为接口没有改变。但是,您应该知道大多数默认构造函数都会创建哈希表(例如 Java 中的?LinkedHashMap)。

支持 Kotlin Maps 的不变性

有趣的是,Kotlin 中maps的标准接口是不可变的。这意味着什么?一旦初始化maps实例,就不能再更改它。减少对象的可变性是最佳实践。例如,开创性的《Effective Java》 一书就推荐了它。这是为什么?不可变对象更容易推理。他们不太容易出现意外错误。您应该尽可能多地使用不可变对象。

话虽如此,有时您确实必须构建可变对象。在 Kotlin 中有第二个接口?MutableMap,它提供写操作。每当您需要修改maps内容时,请使用此方法。完成后,最好将其转换为不可变映射以防止进一步修改。

由于 Kotlin 的简洁语法,初始化一个新maps就像执行以下操作一样简单:

代码语言:javascript复制
val numbers: MutableMap<String, Int> = mutableMapOf(
    "one" to 1,
    "two" to 2,
    "three" to 3,
    "four" to 4,
    "five" to 5
)

现在你有了一个maps实例。让我们来谈谈访问和操作里面的数据需要知道的最相关的方法。

Get

该**?GET**方法查找对应于给定键的映射中的值。

它接收一个参数,这是您要查找的键。它返回与该键关联的值。如果映射中不存在键,则返回null。Kotlin 鼓励?空安全。这就是为什么返回类型被清楚地标记为可空类型的原因。它强制您处理该值可能为空的事实以防止运行时异常。

空安全强制您处理值可能为空的事实以防止运行时异常。

让我们访问我们刚刚定义的映射中的一个值:

代码语言:javascript复制
val value = numbers["three"]
println("value is $value") // will print "value is 3"

等等,那里发生了什么?没有调用get方法。它看起来就像访问一个数组!好吧,它看起来不像,但我们正在调用*get*方法。我们正在使用 Kotlin 的内置?运算符重载,它会自动将类似数组的访问转换为使用get方法。当您阅读它时,它使语法更轻巧且更易于处理。它看起来像?Ruby,具有静态类型的显着优势。

Put

**?Put**的方法有两个目的:

  • 它向映射中插入一个新键,并为其绑定一个提供的值。
  • 它将与现有键关联的值替换为新的值。

我们对两者使用相同的方法。该方法接收一个键和一个值。如果映射中不存在键,则将其与值一起插入。如果它已存在于maps中,则键保持不变,新值替换旧值。

对于插入,该方法返回 null。对于替换,它返回旧值。

让我们看一个例子:

代码语言:javascript复制
numbers.put("six", 6) // numbers["six"] will return 6

如果您不需要旧键的值,您可以使用索引语法,就像使用get 一样

代码语言:javascript复制
numbers["six"] = 6 // numbers["six"] will return 6

Remove

该**?Remove**方法从maps删除一个键和及其相关联的值。

它接收密钥作为参数。它返回值,如果键在maps中不存在,则该值为 null。

代码语言:javascript复制
numbers.remove("three") // numbers["three"] will return null

如果您想无条件删除密钥,请使用上一个调用。但是,这种方法有一个变体。相反,您可以同时提供键和值。在这种情况下,只有当键存在且值与您提供的值匹配时,映射才会删除该对。

代码语言:javascript复制
numbers.remove("three", 2) // Won't remove the pair
numbers.remove("three", 3) // Will remove the pair

这三种方法包括插入、替换、访问和删除元素。这是您在代码中使用maps所需的最低限度。但是,这些接口的 API 比这更广泛。还有更多的方法可以以您可以想象的任何方式与maps进行交互。我将提到另外两种您经常使用的方法。

Clear

该**?Clear** 方法删除maps中的所有项目。

它不接收或返回任何参数。它清空maps,将maps的大小设置回零。使用此操作后,您将无法访问之前存在的任何键或值。

代码语言:javascript复制
numbers.clear() // numbers.size will be 0

从本质上讲,这类似于创建新maps并从头开始。

Iterator

该**?Iterator** 方法是有来遍历map的内容。

具体来说,它返回一个迭代器对象。从某种意义上说,您使用迭代器将maps转换为列表。您可以使用此对象遍历映射中的每个(键、值)对:

代码语言:javascript复制
val iterator = numbers.iterator()
while (iterator.hasNext()) {
    val (key, value) = iterator.next()
    println("$key -> $value") // prints each pair like this "one -> 1"
}

不过,您很少会在实际代码中看到这种语法。Iterator是另一个在 Kotlin 中具有替代语法的运算符,它使代码更加简洁明了:

代码语言:javascript复制
for ((key, value) in numbers) {
    println("$key -> $value") // prints each pair like this "one -> 1"
}

这个块和以前一样,但它的可读性明显更高。如您所见,可读性是 Kotlin 的一个重要因素。

迭代器是一个基本的构建块。最重要的是,还有很多其他方法可以查看maps并按照您想要的方式对其进行操作。一些示例是方便的方法,例如forEachmapfilter

maps是核心抽象

关于maps还有很多要说的。请务必查看 API 参考,因为这里有比我向您展示的方法更多的方法。如果您需要以不同的方式与maps进行交互,很可能存在适合您需求的操作。

maps无处不在。你会经常使用它们。幸运的是,Kotlin 为您提供了保障。基础maps类方便、易于使用,并且涵盖了大量用例。它经过彻底测试和高度优化。当您可以重用其功能时,不要尝试重新发明轮子

0 人点赞