欢迎光临散文网 会员登陆 & 注册

DEVLOG 11.4 Kotlin Collections vs Java Collections

2021-11-04 10:25 作者:房顶上的铝皮水塔  | 我要投稿


  1. Kotlin中的集合的设计理念

  2. range progression

  3. Kotlin中的集合和Java中的集合的互操作


设计理念和基本操作

Kotlin中的集合分成Mutable和Immutable两种类型,可变和不可变这里应该理解为【是否只读】。Kotlin Collection类中只定义了如下的方法:

Collection不是可变的,对应的可变集合应该是MutableCollection,而MutableCollection相对于Collection多了一些增加、删除方法。

我们常用的快捷创建集合的函数listOf创建的是一个List:

在Kotlin中创建Map也非常方便:

等差数列 Arithmetic progression

定义在Progressions.kt 中的只有三种等差数列,IntProgression,CharProgression和LongProgression,当然其他的类型也不太好进行等差。举个例子,IntProgression。等差数列需要的三个基本的量都定义在构造器中:

我们最常用的其实是Progression的其中一种子类型,IntRange:

reversed filter这些扩展函数返回的都是当前range的副本。


和Java中的集合的互操作

虽然Kotlin中的集合定义看起来像另外一套系统,并且定义在java.utils包中的ArrayList这些类明显和后来定义在Kotlin Collection中的List以及MutableList没有明显的继承关系,但是在一些情况下,好像可以对于List和MutableList进行【向下转型】成ArrayList,比如:

看起来是一个【向下转型】,但是实际上是怎么做的呢?具体得看看Iterable的扩展函数toList:

也就是说,range(本身是一个Iterable),它在toList的时候,底层就是会新建一个ArrayList并返回,这伪装成了一个向下转型的操作。

WAIT WAIT WAIT

我真的麻了,Java中先定义的ArrayList怎么会变成后面Kotlin定义的MutableList的子类型?

在Kotlin的github仓库,我们可以看到ArrayList在Kotlin stdlib中的定义:

expect关键字表示Kotlin会从当前的平台找到对应的ArrayList的支持,在JVM上,它的支持就是:

所以Kotlin中的ArrayList是套皮了java.util中的ArrayList,但是在形式上还真的是一个MutableList。


因此Kotlin和Java的Collection确实是两个分开的系统,我们不能随便拿一个toList就认为可以转化成Java的集合中的类型。

一个失败的例子

Iterable.toList会返回一个ArrayList,那我这样写应该没问题了吧:

但是会出错:

具体看看代码:

最后返回的是Java的Arrays里面一个叫做ArrayList的子类,并不是我们的ArrayList。


所以分析一下这里的性能消耗,range.toList创建了一个ArraylistKt,然后sortedByDescending又转化成了Array进行比较,即使这行代码可以运行,性能损失也是比较大的。

为了语法上通过,我们应该这样写:

两者的性能没有提升,Kotlin这种操作用起来爽是很爽,但是性能上不一定占优势


DEVLOG 11.4 Kotlin Collections vs Java Collections的评论 (共 条)

分享到微博请遵守国家法律