配列
配列は、同じ型またはそのサブタイプの固定数の値を保持するデータ構造です。Kotlin で最も一般的な配列の型は、Array
クラスで表現されるオブジェクト型配列です。
NOTE
オブジェクト型配列でプリミティブ型を使用すると、プリミティブ型がオブジェクトにボックス化されるため、パフォーマンスに影響があります。ボックス化のオーバーヘッドを避けるには、代わりにプリミティブ型配列を使用してください。
配列を使用する場合
Kotlin で配列を使用するのは、満たすべき特殊な低レベル要件がある場合です。たとえば、通常のアプリケーションに必要とされる以上のパフォーマンス要件がある場合や、カスタムデータ構造を構築する必要がある場合です。このような種類の制限がない場合は、代わりにコレクションを使用してください。
コレクションには配列と比較して以下の利点があります。
- コレクションは読み取り専用にすることができ、これによりより多くの制御が可能になり、意図が明確な堅牢なコードを記述できます。
- コレクションへの要素の追加や削除は簡単です。これに対し、配列はサイズが固定されています。配列から要素を追加または削除する唯一の方法は、その都度新しい配列を作成することであり、これは非常に非効率的です。
fun 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>()
NOTE
Kotlin の型推論により、空の配列の型は代入の左辺または右辺で指定できます。
例:
var 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
}
NOTE
ほとんどのプログラミング言語と同様に、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]]]
}
NOTE
入れ子になった配列は、同じ型や同じサイズである必要はありません。
要素へのアクセスと変更
配列は常に可変です。配列内の要素にアクセスして変更するには、インデックスアクセス演算子[]
を使用します。
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
}
DANGER
配列の内容を比較するために、等値 (==
) および非等値 (!=
) 演算子を使用しないでください。これらの演算子は、代入された変数が同じオブジェクトを指しているかどうかを確認します。
Kotlin の配列がこのように動作する理由の詳細については、弊社のブログ記事を参照してください。
配列の変換
Kotlin には、配列を変換するための多くの便利な関数があります。このドキュメントではいくつかを取り上げていますが、これは網羅的なリストではありません。関数の完全なリストについては、弊社のAPI リファレンスを参照してください。
合計 (Sum)
配列内のすべての要素の合計を返すには、.sum()
関数を使用します。
fun main() {
val sumArray = arrayOf(1, 2, 3)
// Sums array elements
println(sumArray.sum())
// 6
}
NOTE
.sum()
関数は、Int
のような数値データ型の配列でのみ使用できます。
シャッフル (Shuffle)
配列内の要素をランダムにシャッフルするには、.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
}
NOTE
プリミティブ型配列をオブジェクト型配列に変換するには、.toTypedArray()
関数を使用します。
オブジェクト型配列をプリミティブ型配列に変換するには、.toBooleanArray()
、.toByteArray()
、.toCharArray()
などを使用します。