为什么在Kotlin中仅使用[列表,地图,集合]集合?

Joh*_*ker 1 collections kotlin

我一直在学习Kotlin,并且遇到过Collections API。在Kotlin之前,我一直在学习Java,并且我知道Java中有很多不同类型的Collections API。例如,List, Map, Queue, Set我们使用ArrayList, HashMap, LinkedList, LinkedMap诸如此类,而不是常规类型。尽管在Kotlin中,我们仅使用诸如此类的常规类型,Map, List, Set但是我们也可以使用诸如此类HashMap。你能帮我弄清楚吗?

zsm*_*b13 5

尽管Kotlin最初的主要目标是JVM,但JetBrains大力推动使其成为多平台的,并且也支持JS和Native。

如果您在JVM上使用Kotlin,则所使用的任何集合的实现仍将是原始JDK类,例如java.util.ArrayListjava.util.HashSet。Kotlin标准库没有重新实现这些功能,它具有一些很大的好处:

  • 这些都是经过良好测试的实现,仍然可以维护。
  • 使用完全相同的类使与Java互操作变得轻而易举,因为您可以在不进行任何转换或映射的情况下来回传递它们。

什么科特林确实做的是推出自己的集合语义这些现有的实现,在标准库接口,如形式ListMapMutableListMutableMap等等。一点点的编译器魔术使它也可以由现有的JDK类实现。


如果你不需要某种类型的集合的具体实现,你可以通过这些接口以及标准库(各自的工厂方法使用你的收藏listOfmapOfmutableListOfmutableMapOf,等)。这使您的代码更加通用,并且独立于具体的基础实现。您不知道标准库mutableListOf函数将为您创建哪个特定的类,只是它将是满足MutableList接口协定的对象。

您基本上应该在代码中默认使用这些接口,尤其是在公共API中:

  • 在使用函数参数的情况下,这使客户端可以向函数提供他们希望提供给您的集合的任何实现。如果您的函数可以在上执行任何操作List,则应仅要求该接口-没有理由要求ArrayListLinkedList特别要求。
  • 如果这是返回类型,则使用这些接口可以让您更改将来在内部创建的特定实现,而不会破坏客户端代码。您可以保证只返回一个MutableList东西,而该列表所支持的实现不会向您的客户公开。

如果您查看Kotlin标准库的所有集合处理功能,您将在表面上看到它们几乎完全在这些接口上运行。如果深入研究,您会发现ArrayList正在创建实例,但这不会暴露给客户端代码,因为它通常不必关心具体的实现。


再次回到多平台点,如果您以仅依赖Kotlin标准库定义的类型的方式编写代码,则该代码将可轻松用于非JVM目标。如果kotlin.MutableList在导入中引用,则可以立即将其编译为JS代码,因为每个平台上都有该接口的Kotlin标准库实现。无论是直接映射到现有类,以某种方式包装现有类,还是从头开始为Kotlin实现,都不必担心。但是,如果您java.util.TreeSet在代码中进行引用,那将无法实现JS目标,因为那里没有Java平台类。


您还能java.util.ArrayList直接使用类吗?当然。

  • 如果您在某个时候看不到代码跨平台运行,那么直接使用Java集合是完全可以的。
  • 如果你需要一个具体的实施ListSet性能方面的原因,有时你必须直接使用Java类。

有趣的是,在Kotlin的最新版本中,这些特定类型的实现(例如,基于数组的列表)也包装在标准库的类型别名下,因此默认情况下它们是独立于平台的:请参见kotlin.collections.ArrayListkotlin.collections.HashSet举例说明。这些Kotlin定义的类型通常会在IntelliJ完成中首先显示,因此您会发现自己被迫尽可能使用它们。多数例外情况也一样,例如IllegalArgumentException


TL; DR:您可以在Kotlin中使用两种Java类型的Kotlin集合类型,但是您应该尽可能地使用Java类型。