我一直在学习Kotlin,并且遇到了Collections API。在Kotlin之前,我一直在学习Java,并且我知道Java中有很多不同类型的Collections API。例如,我们使用List, Map, Queue, Set
等代替常规ArrayList, HashMap, LinkedList, LinkedMap
。尽管在Kotlin中,我们仅使用常规类型,例如Map, List, Set
,但也可以使用HashMap
等。因此,那里发生了什么事?你能帮我弄清楚吗?
答案 0 :(得分:4)
虽然Kotlin最初的主要目标是JVM,但JetBrains大力推动使其成为multiplatform,并同时支持JS和Native。
如果您在JVM上使用Kotlin,则您使用的任何集合的实现仍将是原始JDK类,例如java.util.ArrayList
或java.util.HashSet
。 Kotlin标准库没有重新实现这些功能,它具有很多优点:
Kotlin所做的是在这些现有实现的基础上引入它们自己的集合语义,它们以标准库接口的形式出现,例如List
,Map
,{{1 }},MutableList
等。只需compiler magic的一小部分,现有的JDK类也可以实现这些接口。
如果您不需要特定类型的集合的特定实现,则可以通过这些接口以及标准库的相应工厂方法(MutableMap
,listOf
,{ {1}},mapOf
等)。这使您的代码更加通用,并且独立于具体的基础实现。您不知道标准库mutableListOf
函数将为您创建哪个特定类,只是它将是满足mutableMapOf
接口协定的对象。
您基本上应该在代码中默认使用这些接口,尤其是在公共API中:
mutableListOf
上执行任何操作,则应仅请求该接口-没有理由专门要求MutableList
或List
。ArrayList
的东西,而支持该列表的实现不会向您的客户公开。如果您查看Kotlin标准库的所有collection handling functions,您会发现从表面上看,它们几乎完全在这些接口上运行。如果深入研究,您会发现正在创建LinkedList
个实例,但这不会暴露给客户端代码,因为它通常不必关心具体的实现。
再次回到多平台点,如果您以仅依赖Kotlin标准库定义的类型的方式编写代码,则该代码将很容易用于非JVM目标。如果在导入中引用MutableList
,则可以立即编译为JS代码,因为每个平台上都有该接口的Kotlin标准库实现。无论是直接映射到现有类,以某种方式包装现有类,还是从头开始为Kotlin实施,都不必担心。但是,如果您在代码中引用ArrayList
,那将无法实现JS目标,因为那里没有Java平台类。
您是否仍可以直接使用诸如kotlin.MutableList
之类的类?当然可以。
java.util.TreeSet
或java.util.ArrayList
的特定实现,则有时必须直接使用Java类。有趣的是,在Kotlin的最新版本中,这些特定类型的实现(例如,基于数组的列表)也包装在标准库类型别名下,因此默认情况下它们与平台无关:请参见kotlin.collections.ArrayList
或{ {3}}例如。这些Kotlin定义的类型通常会在IntelliJ完成中首先出现,因此您会发现自己被迫尽可能使用它们。对于大多数例外情况也是如此,例如kotlin.collections.HashSet
。
TL; DR:您可以在Kotlin中使用Java类型的Kotlin集合类型,但是您应该尽可能地使用Java类型。