配列
配列とは、同じ型またはそのサブタイプの固定数の値を保持するデータ構造です。Kotlin で最も一般的な配列の型は、Array
クラスで表現されるオブジェクト型配列です。
オブジェクト型配列でプリミティブ(型)を使用すると、プリミティブがオブジェクトにボックス化されるため、パフォーマンスに影響を与えます。ボックス化のオーバーヘッドを避けるには、代わりにプリミティブ型配列を使用してください。
配列を使う場面
Kotlin で配列を使用するのは、満たすべき特殊な低レベル要件がある場合です。例えば、通常のアプリケーションに求められる以上のパフォーマンス要件がある場合や、カスタムデータ構造を構築する必要がある場合などです。このような制限がない場合は、代わりにコレクションを使用してください。
コレクションには、配列と比較して以下の利点があります。
コレクションは読み取り専用にすることができ、これにより、より多くの制御が可能になり、意図が明確で堅牢なコードを記述できます。
コレクションの要素は簡単に追加または削除できます。比較して、配列はサイズが固定されています。配列から要素を追加または削除する唯一の方法は、その都度新しい配列を作成することであり、これは非常に非効率的です。
kotlinfun main() { var riversArray = arrayOf("Nile", "Amazon", "Yangtze") // Using the += assignment operation creates a new riversArray, // copies over the original elements and adds "Mississippi" riversArray += "Mississippi" println(riversArray.joinToString()) // Nile, Amazon, Yangtze, Mississippi }
等値演算子 (
==
) を使用して、コレクションが構造的に等しいかどうかをチェックできます。この演算子を配列に使うことはできません。代わりに、特別な関数を使用する必要があり、これについては「配列の比較」で詳しく読むことができます。
コレクションの詳細については、「コレクションの概要」を参照してください。
配列の作成
Kotlin で配列を作成するには、以下を使用できます。
arrayOf()
、arrayOfNulls()
、emptyArray()
などの関数。Array
コンストラクター。
この例では、arrayOf()
関数を使用し、項目値を渡しています。
fun main() {
// Creates an array with values [1, 2, 3]
val simpleArray = arrayOf(1, 2, 3)
println(simpleArray.joinToString())
// 1, 2, 3
}
この例では、arrayOfNulls()
関数を使用して、指定されたサイズの null
要素で埋められた配列を作成しています。
fun main() {
// Creates an array with values [null, null, null]
val nullArray: Array<Int?> = arrayOfNulls(3)
println(nullArray.joinToString())
// null, null, null
}
この例では、emptyArray()
関数を使用して空の配列を作成しています。
var exampleArray = emptyArray<String>()
Kotlin の型推論により、空の配列の型を代入の左辺または右辺で指定できます。
例:
Kotlinvar exampleArray = emptyArray<String>() var exampleArray: Array<String> = emptyArray()
Array
コンストラクターは、配列のサイズと、インデックスを指定して配列要素の値を返す関数を受け取ります。
fun main() {
// Creates an Array<Int> that initializes with zeros [0, 0, 0]
val initArray = Array<Int>(3) { 0 }
println(initArray.joinToString())
// 0, 0, 0
// Creates an Array<String> with values ["0", "1", "4", "9", "16"]
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { print(it) }
// 014916
}
ほとんどのプログラミング言語と同様に、Kotlin のインデックスは 0 から始まります。
ネストされた配列
配列は互いにネストして多次元配列を作成できます。
fun main() {
// Creates a two-dimensional array
val twoDArray = Array(2) { Array<Int>(2) { 0 } }
println(twoDArray.contentDeepToString())
// [[0, 0], [0, 0]]
// Creates a three-dimensional array
val threeDArray = Array(3) { Array(3) { Array<Int>(3) { 0 } } }
println(threeDArray.contentDeepToString())
// [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
}
ネストされた配列は、同じ型や同じサイズである必要はありません。
要素へのアクセスと変更
配列は常に可変です。配列内の要素にアクセスし、変更するには、インデックスアクセス演算子[]
を使用します。
fun main() {
val simpleArray = arrayOf(1, 2, 3)
val twoDArray = Array(2) { Array<Int>(2) { 0 } }
// Accesses the element and modifies it
simpleArray[0] = 10
twoDArray[0][0] = 2
// Prints the modified element
println(simpleArray[0].toString()) // 10
println(twoDArray[0][0].toString()) // 2
}
Kotlin の配列は_不変 (invariant)_ です。これは、潜在的な実行時エラーを防ぐため、Kotlin では Array<String>
を Array<Any>
に代入することを許可しないことを意味します。代わりに、Array<out Any>
を使用できます。詳細については、「型プロジェクション」を参照してください。
配列の操作
Kotlin では、配列を使用して可変個の引数を関数に渡したり、配列自体に対して操作を実行したりできます。例えば、配列の比較、内容の変換、またはコレクションへの変換などです。
可変個引数を関数に渡す
Kotlin では、vararg
パラメーターを介して可変個の引数を関数に渡すことができます。これは、メッセージのフォーマットや SQL クエリの作成など、引数の数が事前にわからない場合に役立ちます。
可変個の引数を含む配列を関数に渡すには、スプレッド演算子 (*
) を使用します。スプレッド演算子は、配列の各要素を個別の引数として選択した関数に渡します。
fun main() {
val lettersArray = arrayOf("c", "d")
printAllStrings("a", "b", *lettersArray)
// abcd
}
fun printAllStrings(vararg strings: String) {
for (string in strings) {
print(string)
}
}
詳細については、「可変個引数 (varargs)」を参照してください。
配列の比較
2つの配列が同じ要素を同じ順序で持っているかどうかを比較するには、.contentEquals()
および .contentDeepEquals()
関数を使用します。
fun main() {
val simpleArray = arrayOf(1, 2, 3)
val anotherArray = arrayOf(1, 2, 3)
// Compares contents of arrays
println(simpleArray.contentEquals(anotherArray))
// true
// Using infix notation, compares contents of arrays after an element
// is changed
simpleArray[0] = 10
println(simpleArray contentEquals anotherArray)
// false
}
配列の内容を比較するために、等値 (
==
) および不等値 (!=
) 演算子を使用しないでください。これらの演算子は、割り当てられた変数が同じオブジェクトを指しているかどうかをチェックします。Kotlin の配列がこの挙動を示す理由について詳しく知るには、当社のブログ投稿を参照してください。
配列の変換
Kotlin には、配列を変換するための多くの便利な関数があります。このドキュメントではいくつかを取り上げていますが、これが網羅的なリストではありません。関数の完全なリストについては、当社のAPI リファレンスを参照してください。
合計
配列内の全要素の合計を返すには、.sum()
関数を使用します。
fun main() {
val sumArray = arrayOf(1, 2, 3)
// Sums array elements
println(sumArray.sum())
// 6
}
.sum()
関数は、Int
などの数値データ型の配列でのみ使用できます。
シャッフル
配列内の要素をランダムにシャッフルするには、.shuffle()
関数を使用します。
fun main() {
val simpleArray = arrayOf(1, 2, 3)
// Shuffles elements [3, 2, 1]
simpleArray.shuffle()
println(simpleArray.joinToString())
// Shuffles elements again [2, 3, 1]
simpleArray.shuffle()
println(simpleArray.joinToString())
}
配列をコレクションに変換する
配列を使用するものとコレクションを使用するものが混在する異なる API を扱う場合、配列をコレクションに変換したり、その逆を行ったりすることができます。
List または Set への変換
配列を List
または Set
に変換するには、.toList()
および .toSet()
関数を使用します。
fun main() {
val simpleArray = arrayOf("a", "b", "c", "c")
// Converts to a Set
println(simpleArray.toSet())
// [a, b, c]
// Converts to a List
println(simpleArray.toList())
// [a, b, c, c]
}
Map への変換
配列を Map
に変換するには、.toMap()
関数を使用します。
Pair<K,V>
の配列のみが Map
に変換できます。Pair
インスタンスの最初の値がキーになり、2番目の値が値になります。この例では、中置記法を使用してto
関数を呼び出し、Pair
のタプルを作成しています。
fun main() {
val pairArray = arrayOf("apple" to 120, "banana" to 150, "cherry" to 90, "apple" to 140)
// Converts to a Map
// The keys are fruits and the values are their number of calories
// Note how keys must be unique, so the latest value of "apple"
// overwrites the first
println(pairArray.toMap())
// {apple=140, banana=150, cherry=90}
}
プリミティブ型配列
Array
クラスをプリミティブ値で使用すると、これらの値はオブジェクトにボックス化されます。代替策として、プリミティブ型配列を使用すると、ボックス化のオーバーヘッドという副作用なしにプリミティブを配列に格納できます。
プリミティブ型配列 | Javaでの同等な型 |
---|---|
BooleanArray | boolean[] |
ByteArray | byte[] |
CharArray | char[] |
DoubleArray | double[] |
FloatArray | float[] |
IntArray | int[] |
LongArray | long[] |
ShortArray | short[] |
これらのクラスは Array
クラスとの継承関係はありませんが、同じ関数とプロパティのセットを持っています。
この例では、IntArray
クラスのインスタンスを作成しています。
fun main() {
// Creates an array of Int of size 5 with the values initialized to zero
val exampleArray = IntArray(5)
println(exampleArray.joinToString())
// 0, 0, 0, 0, 0
}
プリミティブ型配列をオブジェクト型配列に変換するには、
.toTypedArray()
関数を使用します。オブジェクト型配列をプリミティブ型配列に変換するには、
.toBooleanArray()
、.toByteArray()
、.toCharArray()
などを使用します。