首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Kotlin有默认地图吗?

您以前使用过默认地图或默认字典吗?如果你对Python有所了解,你可能会在某些时候看到它的实际效果。Kotlin还附带了一个类似的工具,我想在这篇小文章中展示。

您可以在此处找到Python文档和一些示例,但基本用例显示在以下代码段中:

它也可以与其他类型一起使用,并确保在运行代码时不会得到它。相反,它为未知键提供了一个默认值,这对于分组和计算算法非常有用,如下所示:

在这篇文章中,我想向您展示Kotlin如何处理地图的默认值以及其他替代方案。

一个简单的问题

假设我们想要编写一个泛型函数,该函数接受一个集合并返回一个映射,该映射包含与其出现次数相关的原始集合中的元素:

虽然在科特林(当然)有一种自然而简单的功能式方法,但我们首先要考虑一些迭代方法。让我们从以下开始吧。

没有默认值的迭代解决方案

funcountOccurrences(values:Collection):Map{

valcountMap=mutableMapOf()

for(einvalues) {

valcurrent=countMap[e]

if(current==null)countMap[e]=1

elsecountMap[e]=current+1

}

returncountMap

}

Target platform: JVMRunning on kotlin v. 1.3.41

我们可以使用a算法。迭代所有值时,我们会查看地图以查看之前是否已经看到过。如果是这样,我们增加柜台;否则,我们将初始计数放入地图中。下一部分将显示一个类似但改进的解决方案。

具有显式默认值的迭代解决方案

countMap。putIfAbsent(e,)

// getValue ,作为索引运算符的替代,确保返回不可为空的类型

countMap[e]=countMap。getValue(e)+1

目标平台:JVM上科特林V上运行。1.3.41

作为前一解决方案的替代方案,我们可以利用确保元素初始化为0,以便我们可以安全地增加以下行中的计数器。在这种情况下我们做的是提供显式默认值。另一个类似的工具是:

countMap[e]=countMap。getOrDefault(e,)+1

目标平台:JVM上科特林V上运行。1.3.41

提供明确的默认值或通过简单易懂的解决方案,但我们可以做得更好。

具有隐式默认值的迭代解决方案

类似Python的,科特林提供了一个整洁的扩展名为,它看起来是这样的:

这个扩展让我们为地图中没有关联值的键提供初始化程序。让我们在我们的解决方案中使用它:

funcountOccurrences(values:Collection):Map{

valcountMap=mutableMapOf()。withDefault{}

for(einvalues){

countMap[e]=countMap。getValue(e)+1

}

返回countMap

}

目标平台:JVM上科特林V上运行。1.3.41

它进一步简化了代码,因为我们不再需要在迭代中处理未知值。由于我们使用的是默认地图,因此我们可以安全地从中获取值并随时增加计数器。

重要的提示

使用扩展时需要注意一件重要的事情,这是其文档的一部分:

[...]当原始地图不包含指定键的值时使用此隐式默认值,并使用[Map.getValue]函数[...]获取值

只有在使用时才会提供默认值,这在使用索引运算符访问地图时不是这种情况,如此处所示(点击运行按钮):

funmain(){

valmap=mutableMapOf()。withDefault{}

println(map[“hello”])

的println(地图。的getValue(“你好”))

}

目标平台:JVM上科特林V上运行。1.3.41

原因是界面的合同,其中说:

返回与给定[key]对应的值,或者如果地图中不存在这样的键。

由于默认地图想要履行这个合同,他们不能返回任何东西,但是在不存在密钥的情况下,这已经在Kotlin论坛中讨论过了。

让我们去惯用吧

好吧,所以看到Kotlin确实带有地图中的默认值,这太棒了。但是,编写代码是不是像上面的例子中那样惯用?我认为这取决于。使用Kotlin出色的功能API可以更简单地解决大多数情况,这些API带有内置的分组和计数功能。然而,了解替代方案是很好的,因为在某些情况下,您可能会选择采用迭代方法。让我为您提供代码的简化版本:

funcountOccurrences(values:Collection):Map=

mutableMapOf().withDefault{}.apply{

for(einvalues) {

put(e,getValue(e)+1)

}

}

它仍然使用显式循环,但通过使用它简化了允许我们在单个语句中初始化映射。

在Kotlin中有很多方法可以解决给定的问题,但最简单的方法可能是一种功能性方法:

funcountOccurrences(values:Collection):Map=

价值观。groupingBy{it}。eachCount()

目标平台:JVM上科特林V上运行。1.3.41

结论

如本小文所示,您可以使用Kotlin以多种不同方式解决简单算法。与Python类似,您可以使用默认值提供程序初始化映射,但需要注意常规索引操作访问将无法按预期方式工作。如文档所述,必须使用该功能。由于Kotlin附带了一个非常有用的标准库,因此您需要考虑尽可能多地使用它。这意味着在大多数情况下,实现分组或计数等常见事项不应从头开始实现,而应使用标准库中的现有功能来实现。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190719A074W900?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券