はじめに
前回のKotlin基本文法編に続きまして、今回は前回お話した基本データ型をまとまりとして取り扱う方法を記載したいと思います。
Kotlinでは、配列やレンジ、そしてコレクション(リスト、セット、マップ)があり、多用することになりますので、一つずつ解説していきます。
配列
Kotlinの配列は、Arrayクラスにより表現されています。後ほど、紹介する配列は宣言時に要素数などを決めておく必要があります。
先ずは、配列の宣言方法について
1 2 3 4 5 6 7 8 | // サイズだけ宣言して、nullで初期化 var strNullArray = arrayOfNulls<String>(3) // 文字列の配列で初期値あり var strArray = arrayOf<String>("A", "B", "C") // プリミティブ型の配列(Int, Char, Byte, Shortなどはオーバーヘッド無しでボクシングができる) var intArray = intArrayOf(1, 2, 3) // Array<String>を["0", "2", "4"]の値で初期化 var twiceStrArray = Array(3, { i -> (i * 2).toString() }) |
次に要素の取得、代入について
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var strArray = arrayOf<String>("A", "B", "C") // 取得 println(strArray[0]) println(strArray[1]) println(strArray[2]) // 代入 strArray[0] = "a" strArray[1] = "b" strArray[2] = "c" // 添え字でのループ for (index in strArray.indices) { println("$index : ${strArray[index]}") } // 要素でのループ for (element in strArray) { println("$element") } // forEachを使った要素でのループ strArray.forEach{element -> println("$element")} // おまけ:配列の要素数の取得 println(strArray.size) |
レンジ
Kotlinにも他の言語と同様に「1..5」のように表現できるレンジというものがあります。こちらは実際のコードを見てもらえれば、概要はつかめると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // 宣言とforでの繰り返し >>> var intRange: IntRange = 10..20 >>> for (i in intRange) { ... println(i) ... } 10 11 12 13 14 15 16 17 18 19 20 // 1から10までのリスト >>> (1..10).toList() [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // 10から1までのリスト >>> (1..10).reversed().toList() [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] // 10から1までのリスト >>> (10 downTo 1).toList() [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] // 1から10までで、2刻みのリスト >>> (1..10 step 2).toList() [1, 3, 5, 7, 9] |
コレクション(リスト)
コレクションを使うことは他の言語であっても非常に多用するのではないでしょうか。KotlinはJavaとは異なり、イミュータブル(変更不可能)なものとミュータブル(変更可能)なものを明確に区別しています。ミュータブルなコレクションは要素を変更したり、追加・削除が可能です。
先ずは、イミュータブルなリストの例です。0番目の要素の変更や要素の追加でエラーが発生しているのがわかると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | >>> val intList = listOf<Int>(1, 2, 3) >>> intList.size 3 >>> intList[0] 1 >>> intList[0] = 10 error: unresolved reference. None of the following candidates is applicable because of receiver type mismatch: @InlineOnly public operator inline fun <K, V> MutableMap<Int, Int>.set(key: Int, value: Int): Unit defined in kotlin.collections @InlineOnly public operator inline fun kotlin.text.StringBuilder /* = java.lang.StringBuilder */.set(index: Int, value: Char): Unit defined in kotlin.text intList[0] = 10 ^ error: no set method providing array access intList[0] = 10 ^ >>> intList += 10 java.lang.IllegalAccessError: tried to access field Line13.intList from class Line17 |
今度は、ミュータブルなリストです。要素の変更、追加、削除などの操作が可能であることがわかると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // 要素の変更 >>> mutableIntList[0] 1 >>> mutableIntList[0] = 10 >>> mutableIntList[0] 10 >>> mutableIntList.size 3 // 要素の追加 >>> mutableIntList += 20 >>> mutableIntList.size 4 >>> mutableIntList[3] 20 // 1番目の要素の削除 >>> mutableIntList [10, 2, 3, 20] >>> mutableIntList.removeAt(1) 2 >>> mutableIntList [10, 3, 20] |
なお、イミュータブルなリストをイミュータブルなリストには下記のメソッドで変更可能です。
1 2 3 4 5 6 7 | >>> val intList = listOf<Int>(1, 2, 3) >>> val mutableIntList = intList.toMutableList() >>> mutableIntList [1, 2, 3] >>> mutableIntList += 4 >>> mutableIntList [1, 2, 3, 4] |
コレクション(セット)
セットもリスト同じように扱えますが、集合を表すコレクションで下記のような特徴があります。
- リストとは異なり、集合のため要素に重複がなくなります。
- リストとは異なり、順序が保証されていません
それでは、早速例を見てみましょう。使い方としてはリストと大差ありませんね。
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 重複を持たない >>> val intSet = setOf<Int>(1, 2, 3, 3, 2, 1) >>> intSet [1, 2, 3] // MutableSetは要素の変更が可能 >>> val mutableIntSet = mutableSetOf<Int>(1, 2, 3, 3, 2, 1) >>> mutableIntSet += 4 >>> mutableIntSet [1, 2, 3, 4] >>> mutableIntSet -= 3 >>> mutableIntSet [1, 2, 4] |
コレクション(マップ)
コレクションの最後としてマップを紹介します。マップは、キーと値の組みを保持するコレクションです。Pairオブジェクト「”key” to “value”」を保持するのですが、この書き方が他の言語と比べると少しクセがありますが、慣れれば問題ないでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | >>> val intMap = mapOf<String, Int>("a" to 1, "b" to 2, "c" to 3) >>> intMap {a=1, b=2, c=3} >>> intMap["a"] 1 // 存在しない要素にアクセスするとnullが返却される >>> intMap["x"] null >>> val mutableIntMap = intMap.toMutableMap() // キーがdで、値が4のPairを追加 >>> mutableIntMap["d"] = 4 >>> mutableIntMap {a=1, b=2, c=3, d=4} // 上記以外にも下記のようにも追加できる(キーがeで、値が5のPairを追加) >>> mutableIntMap += "e" to 5 >>> mutableIntMap {a=1, b=2, c=3, d=4, e=5} |
コレクションまとめ
まとめとして、コレクションの簡単な表を記載しておきます。
インタフェース | 説明 | 初期化メソッド | ミュータブル化 |
List | 変更不可の順序付きリスト | listOf | toMutableList() |
MutableList | 変更可の順序付きリスト | mutableListOf | – |
Set | 変更不可の集合 | setOf | toMutableSet() |
MutableSet | 変更可の集合 | mutableSetOf | – |
Map | 変更不可のキーと値のコレクション | mapOf | toMutableMap() |
MutableMap | 変更可のキーと値のコレクション | mutableMapOf | – |
さいごに
いかがでしたでしょうか。コレクションは非常に多用するので、しっかりと把握しておきましょう。特にJavaからの移行の場合は、イミュータブルとミュータブルが区別されていることは注意ですね。
次回は、コレクションを操作する便利なメソッド群(map、filter、reduceなど)を紹介したいと思います。