DEVLOG 11.4 Kotlin Collections vs Java Collections

Kotlin中的集合的設(shè)計(jì)理念
range progression
Kotlin中的集合和Java中的集合的互操作
設(shè)計(jì)理念和基本操作
Kotlin中的集合分成Mutable和Immutable兩種類型,可變和不可變這里應(yīng)該理解為【是否只讀】。Kotlin Collection類中只定義了如下的方法:
Collection不是可變的,對(duì)應(yīng)的可變集合應(yīng)該是MutableCollection,而MutableCollection相對(duì)于Collection多了一些增加、刪除方法。
我們常用的快捷創(chuàng)建集合的函數(shù)listOf創(chuàng)建的是一個(gè)List:
在Kotlin中創(chuàng)建Map也非常方便:
等差數(shù)列 Arithmetic progression
定義在Progressions.kt 中的只有三種等差數(shù)列,IntProgression,CharProgression和LongProgression,當(dāng)然其他的類型也不太好進(jìn)行等差。舉個(gè)例子,IntProgression。等差數(shù)列需要的三個(gè)基本的量都定義在構(gòu)造器中:
我們最常用的其實(shí)是Progression的其中一種子類型,IntRange:
reversed filter這些擴(kuò)展函數(shù)返回的都是當(dāng)前range的副本。
和Java中的集合的互操作
雖然Kotlin中的集合定義看起來像另外一套系統(tǒng),并且定義在java.utils包中的ArrayList這些類明顯和后來定義在Kotlin Collection中的List以及MutableList沒有明顯的繼承關(guān)系,但是在一些情況下,好像可以對(duì)于List和MutableList進(jìn)行【向下轉(zhuǎn)型】成ArrayList,比如:
看起來是一個(gè)【向下轉(zhuǎn)型】,但是實(shí)際上是怎么做的呢?具體得看看Iterable的擴(kuò)展函數(shù)toList:
也就是說,range(本身是一個(gè)Iterable),它在toList的時(shí)候,底層就是會(huì)新建一個(gè)ArrayList并返回,這偽裝成了一個(gè)向下轉(zhuǎn)型的操作。
WAIT WAIT WAIT
我真的麻了,Java中先定義的ArrayList怎么會(huì)變成后面Kotlin定義的MutableList的子類型?
在Kotlin的github倉庫,我們可以看到ArrayList在Kotlin stdlib中的定義:
expect關(guān)鍵字表示Kotlin會(huì)從當(dāng)前的平臺(tái)找到對(duì)應(yīng)的ArrayList的支持,在JVM上,它的支持就是:

所以Kotlin中的ArrayList是套皮了java.util中的ArrayList,但是在形式上還真的是一個(gè)MutableList。
因此Kotlin和Java的Collection確實(shí)是兩個(gè)分開的系統(tǒng),我們不能隨便拿一個(gè)toList就認(rèn)為可以轉(zhuǎn)化成Java的集合中的類型。
一個(gè)失敗的例子
Iterable.toList會(huì)返回一個(gè)ArrayList,那我這樣寫應(yīng)該沒問題了吧:

但是會(huì)出錯(cuò):

具體看看代碼:
最后返回的是Java的Arrays里面一個(gè)叫做ArrayList的子類,并不是我們的ArrayList。
所以分析一下這里的性能消耗,range.toList創(chuàng)建了一個(gè)ArraylistKt,然后sortedByDescending又轉(zhuǎn)化成了Array進(jìn)行比較,即使這行代碼可以運(yùn)行,性能損失也是比較大的。
為了語法上通過,我們應(yīng)該這樣寫:
兩者的性能沒有提升,Kotlin這種操作用起來爽是很爽,但是性能上不一定占優(yōu)勢(shì)