MutableList
JavaではArrayListを使う場面の多くでKotlinではMutableListを使う。
mutableListOf関数で作成したオブジェクトをArrayListとして扱える?
MutableListについて深く掘り下げてみる。
MutableListはインターフェイス
MutableListの定義を見るとインターフェイス
親のListもMutableCollectionもインターフェイス
Listインターフェイスではリストに特有のメソッド宣言
MutableCollectionでは変更可能なコレクションに特有のメソッド宣言
https://scrapbox.io/files/60ca9a3723ebdc0022f8928e.png
Listインターフェイス
リスト構造なのだからadd, removeは必須。その他のよく使うであろう便利なメソッドも宣言されている。
code:List.kt
public interface MutableCollection<E> : Collection<E>, MutableIterable<E> {
override fun iterator(): MutableIterator<E>
public fun add(element: E): Boolean
public fun remove(element: E): Boolean
public fun addAll(elements: Collection<E>): Boolean
public fun removeAll(elements: Collection<E>): Boolean
public fun retainAll(elements: Collection<E>): Boolean
public fun clear(): Unit
}
Collectionインターフェイス
Collectionインターフェイスはデータの集まりを表現するクラスが備えていなければならないメソッドを宣言している。
code:Collection.kt
public interface Collection<out E> : Iterable<E> {
public val size: Int
public fun isEmpty(): Boolean
public operator fun contains(element: @UnsafeVariance E): Boolean
override fun iterator(): Iterator<E>
public fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean
}
Iteratorインターフェイス
code:Iterator.kt
public interface Iterable<out T> {
public operator fun iterator(): Iterator<T>
}
MutableIteratorインターフェイス
code:MutableIterator.kt
public interface MutableIterable<out T> : Iterable<T> {
override fun iterator(): MutableIterator<T>
}
MutableListの実装
MutableListはあくまでインターフェイス。実装はどうなっているのか?
val menuList: MutableList<MutableMap<String, String>> = mutableListOf()
MutableListを実装したクラスのコンストラクタを呼び出すわけではない。
ではmutableListOfは何を返しているのか?
mutableListOf
mutableListOfは結局のところArrayListのインスタンス返すだけ
arrayListOfも定義されている。これもArrayListのインスタンスを返すだけ
つまり中身はJavaのArrayListである。
code:mutableListOf.kt
@SinceKotlin("1.1")
@kotlin.internal.InlineOnly
public inline fun <T> mutableListOf(): MutableList<T> = ArrayList()
@SinceKotlin("1.1")
@kotlin.internal.InlineOnly
public inline fun <T> arrayListOf(): ArrayList<T> = ArrayList()
ArrayList
Kotlinのパッケージ内でArrayListって宣言されてたっけ?
メソッドの宣言だけ。
expectキーワードがついているので、これはKotlin自身では実装されていない。
code:ArrayList.kt
package kotlin.collections
expect class ArrayList<E> : MutableList<E>, RandomAccess {
constructor()
constructor(initialCapacity: Int)
constructor(elements: Collection<E>)
fun trimToSize()
fun ensureCapacity(minCapacity: Int)
// From List
override val size: Int
override fun isEmpty(): Boolean
override fun contains(element: @UnsafeVariance E): Boolean
override fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean
override operator fun get(index: Int): E
override fun indexOf(element: @UnsafeVariance E): Int
override fun lastIndexOf(element: @UnsafeVariance E): Int
// From MutableCollection
override fun iterator(): MutableIterator<E>
// From MutableList
override fun add(element: E): Boolean
override fun remove(element: E): Boolean
override fun addAll(elements: Collection<E>): Boolean
override fun addAll(index: Int, elements: Collection<E>): Boolean
override fun removeAll(elements: Collection<E>): Boolean
override fun retainAll(elements: Collection<E>): Boolean
override fun clear()
override operator fun set(index: Int, element: E): E
override fun add(index: Int, element: E)
override fun removeAt(index: Int): E
override fun listIterator(): MutableListIterator<E>
override fun listIterator(index: Int): MutableListIterator<E>
override fun subList(fromIndex: Int, toIndex: Int): MutableList<E>
}
expectキーワード
expectキーワードで宣言された識別子はKotlinの外、つまり今の場合はJavaのライブラリが提供している。
expect marks a declaration as platform-specific, expecting an implementation in platform modules.
code:TypeAliases.kt
@file:Suppress("ACTUAL_WITHOUT_EXPECT") // for building kotlin-stdlib-minimal-for-test
package kotlin.collections
@SinceKotlin("1.1") public actual typealias RandomAccess = java.util.RandomAccess
@SinceKotlin("1.1") public actual typealias ArrayList<E> = java.util.ArrayList<E>
@SinceKotlin("1.1") public actual typealias LinkedHashMap<K, V> = java.util.LinkedHashMap<K, V>
@SinceKotlin("1.1") public actual typealias HashMap<K, V> = java.util.HashMap<K, V>
@SinceKotlin("1.1") public actual typealias LinkedHashSet<E> = java.util.LinkedHashSet<E>
@SinceKotlin("1.1") public actual typealias HashSet<E> = java.util.HashSet<E>