Skip to content

配列

配列は、同じ型またはそのサブタイプの値を固定数保持するデータ構造です。 配列の要素は順序付けられており、インデックスによってアクセスされます。

Kotlinは Array<T> クラスと プリミティブ型配列 を提供しています。

配列を使用する場合

Java APIとの相互運用性や低レベルの要件がある場合に配列を使用してください。例えば、一般的なアプリケーションで必要とされる以上のパフォーマンス要件がある場合や、カスタムデータ構造を構築する必要がある場合などです。

ほとんどのユースケースでは、代わりに コレクション を優先して使用してください。

機能配列コレクション
サイズ固定型による
読み取り専用バリアントなし(常に変更可能)あり (ListSet)
要素の追加と削除ネイティブのサポートなし。
新しい配列を割り当ててコピーする
あり(ミュータブルコレクション)
== による構造的な等価性なし(参照を比較)。
代わりに .contentEquals() を使用
あり
プリミティブ値プリミティブ型配列は値を
ボックス化せずに格納
通常はボックス化される
Java相互運用性T[] にマッピングされるjava.util.List および
java.util.Set にマッピングされる
関数型スタイルのフィルタリングと変換限定的広範

配列をコレクションに変換する方法についてはこちらをご覧ください。

配列の作成

配列を作成するには、以下を使用できます:

val で配列を宣言しても、変数の再代入を防ぐだけで、内容が読み取り専用になるわけではありません。 要素は valvar の両方の配列で変更可能です。この区別は参照にのみ影響し、内容には影響しません。 読み取り専用のビューが必要な場合は、代わりに コレクション を使用してください。

値を持つ配列

既知の値のセットから型指定された配列を作成するには、arrayOf() 関数を使用します。 Kotlinは型を自動的に推論します:

kotlin
fun main() {
    val simpleArray = arrayOf(1, 2, 3) // Array<Int>
    println(simpleArray.joinToString())
    // 1, 2, 3
}

空の配列

要素のない配列を作成するには、emptyArray() 関数を使用します。 代入の左側または右側で要素の型を指定できます:

kotlin
val emptyArrayRight = emptyArray<String>()
val emptyArrayLeft: Array<String> = emptyArray()

配列に要素を追加する方法についてはこちらをご覧ください。

nullを含む配列

指定されたサイズで null 要素が入力された配列を作成するには、arrayOfNulls() 関数を使用します:

kotlin
fun main() {
    val nullArray: Array<Int?> = arrayOfNulls(3)
    println(nullArray.joinToString())
    // null, null, null
}

Arrayコンストラクタ

Array コンストラクタは、配列のサイズと、配列要素の値を返す関数を引数に取ります:

kotlin
fun main() {
    val zeroes = Array<Int>(3) { 0 }
    println(zeroes.joinToString())
    // 0, 0, 0
    
    val squares = Array(5) { i -> i * i }
    println(squares.joinToString())
    // 0, 1, 4, 9, 16
}

ネストされた配列

ネストされた配列や多次元配列を作成するには、配列の配列を使用します。 ネストされた配列は、同じ型や同じサイズである必要はありません。

kotlin
fun main() {
    // 2次元配列を作成します
    val twoDArray = Array(2) { Array<Int>(2) { 0 } }
    println(twoDArray.contentDeepToString())
    // [[0, 0], [0, 0]]

    // 3次元配列を作成します
    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]]]
}

プリミティブ型配列

プリミティブ値で Array クラスを使用すると、コンパイラはこれらの値をオブジェクトにボックス化します。 ボックス化のオーバーヘッドを避けるために、専用のプリミティブ型配列を使用できます。 これらは Array<T> クラスのサブクラスではありませんが、同様の関数とプロパティのセットを提供します。

Kotlinの型Javaでの対応
BooleanArrayboolean[]
ByteArraybyte[]
CharArraychar[]
DoubleArraydouble[]
FloatArrayfloat[]
IntArrayint[]
LongArraylong[]
ShortArrayshort[]

Kotlinには専用の StringArray 型はありません。 String はプリミティブではないため、代わりに型推論を伴う arrayOf() または arrayOf<String>() 関数を使用してください。

プリミティブ型配列を作成するには、次のいずれかのオプションを使用します:

  • コンストラクタ関数:

    kotlin
    fun main() {
        // 値がゼロに初期化されたサイズ5のInt配列を作成します
        val primitiveTypeArray = IntArray(5)
        println(primitiveTypeArray.joinToString())
        // 0, 0, 0, 0, 0
    
        // Int配列を作成し、初期化関数を渡します
        val squares = IntArray(5) { i -> i * i }
        println(squares.joinToString())
        // 0, 1, 4, 9, 16
    }
  • ファクトリ関数:

    kotlin
    fun main() {
        // 5つの要素を持つInt配列を作成します
        val numbers = intArrayOf(1, 2, 3, 4, 5)
        println(numbers.joinToString())
        // 1, 2, 3, 4, 5
    
        // 3つの要素を持つChar配列を作成します
        val characters = charArrayOf('K', 't', 'l')
        println(characters.joinToString())
        // K, t, l
    
        // 3つの要素を持つDouble配列を作成します
        val doubles = doubleArrayOf(0.22, 4.16, 0.5)
        println(doubles.joinToString()) 
        // 0.22, 4.16, 0.5
    }

プリミティブ型配列をオブジェクト型配列に変換するには、.toTypedArray() 関数を使用します。

オブジェクト型配列をプリミティブ型配列に変換するには、.toBooleanArray().toByteArray().toCharArray() などを使用します。

配列の操作

配列は、反復、検索、ソート、変換など、コレクションと同じ操作の多くをサポートしています。 Kotlinでは、配列を使用して関数に可変長引数を渡したり、配列自体に対して操作を実行したりできます。 最も一般的なプロパティと関数を以下の表に示します:

メンバー返り値
size要素数
indices有効なインデックスの範囲
lastIndex最後の有効なインデックス
first() および last()最初と最後の要素
isEmpty() および isNotEmpty()配列が空であるか、空でない場合に true
contains()配列にその要素が含まれている場合に true

配列のプロパティと関数の詳細については、APIリファレンスを参照してください。

このセクションでは、最も頻繁に使用される操作のいくつかを紹介します。

要素のアクセスと変更

配列の要素にアクセスして変更するには、インデックスアクセス演算子 ([]) を使用します:

kotlin
fun main() {
    val simpleArray = arrayOf(1, 2, 3)
    val twoDArray = Array(2) { Array<Int>(2) { 0 } }

    // 要素にアクセスして変更します
    simpleArray[0] = 10
    twoDArray[0][0] = 2

    // 変更された要素をプリントします
    println(simpleArray[0]) 
    // 10
    println(twoDArray[0][0]) 
    // 2
}

配列の境界外のインデックスにアクセスしようとすると、Kotlinは実行時に ArrayIndexOutOfBoundsException をスローします。

fill(element, fromIndex, toIndex) 関数を使用して、特定の範囲内の要素をその場で置き換えることもできます。 fromIndex は含まれ、 toIndex は含まれません:

kotlin
fun main() {
    val arr = IntArray(3)
    println(arr.joinToString())
    // 0, 0, 0
    
   arr.fill(1)
   println(arr.joinToString())
   // 1, 1, 1
  
   arr.fill(0, 0, 2)
   println(arr.joinToString())
   // 0, 0, 1
}

Kotlinにおいて、配列は 非変 (invariant) です。これは、Array<String>Array<Any> のサブタイプではないことを意味します。これにより、実行時の型障害の可能性が防がれます。共変性を表現するには、Array<out Any> 型投影 (type projection) を使用します:

kotlin
fun main() {
    fun printArr(arr: Array<out Any>) {
        for (item in arr) print("$item, ")
    }

    printArr(arrayOf("k", "t", "n"))  
    // k, t, n, 
}

要素の追加と削除

配列はサイズが固定されているため、.add() および .remove() 関数をサポートしていません。これらの操作を実行するには、新しい配列を作成する必要があります。そのために、次のいずれかのオプションを使用できます:

  • .copyOf 関数を使用する:

    kotlin
    fun main() {
        var arr = intArrayOf(0, 1, 2)
        
        arr = arr.copyOf(arr.size + 1)
        println(arr.joinToString())
        // 0, 1, 2, 0
    
        arr[arr.lastIndex] = 3
        println(arr.joinToString())
        // 0, 1, 2, 3
    }
  • + または += 演算子を使用する:

    kotlin
    fun main() {
        var arr = intArrayOf(0, 1, 2)
    
        arr += 3
        println(arr.joinToString())
        // 0, 1, 2, 3
    
        arr = arr + intArrayOf(4, 5)
        println(arr.joinToString())
        // 0, 1, 2, 3, 4, 5
    }

要素を頻繁に追加または削除する必要がある場合は、代わりに ミュータブルコレクション を使用してください。

配列の比較

2つの配列が同じ要素を同じ順序で持っているかどうかを比較するには、.contentEquals() および .contentDeepEquals() 関数を使用します:

kotlin
fun main() {
    val simpleArray = arrayOf(1, 2, 3)
    val anotherArray = arrayOf(1, 2, 3)

    // 配列の内容を比較します
    println(simpleArray.contentEquals(anotherArray))
    // true

    // 中置表記法を使用して、要素が変更された後の配列の内容を比較します
    simpleArray[0] = 10
    println(simpleArray contentEquals anotherArray)
    // false
}

配列の内容を比較するために、等価 (==) および不等 (!=) 演算子 を使用しないでください。これらの演算子は、割り当てられた変数が同じオブジェクトを指しているかどうかをチェックします。

Kotlinの配列がこのように動作する理由の詳細については、こちらの ブログ記事 を参照してください。

配列の変換

Kotlinには配列を変換するための便利な関数が数多くあります。このセクションではその一部を紹介します。 完全なリストについては、APIリファレンスを参照してください。

合計 (Sum)

配列内のすべての要素の合計を返すには、.sum() 関数を使用します:

kotlin
fun main() {
    val sumArray = arrayOf(1, 2, 3)
    println(sumArray.sum())
    // 6
}

.sum() 関数は、Int などの 数値データ型 の配列にのみ使用できます。

ソートとシャッフル

.sort() 関数を使用して配列内の要素を自然な順序でソートしたり、.shuffle() 関数を使用してランダムにシャッフルしたりできます。

kotlin
fun main() {
    val simpleArray = arrayOf(1, 2, 3)

    // 要素をランダムにシャッフルします
    simpleArray.shuffle()
    println(simpleArray.joinToString())
  
    // 要素をソートします
    simpleArray.sort()
    println(simpleArray.joinToString())
    // 1, 2, 3
}

元の配列を変更せずに新しいソート済み配列を取得するには、代わりに .sortedArray() 関数を使用します。

関数への可変長引数の受け渡し

Kotlinでは、vararg パラメータを介して関数に可変長引数を渡すことができます。これは、メッセージのフォーマットやSQLクエリの作成時のように、引数の数が事前にわからない場合に便利です。

可変長引数を含む配列を関数に渡すには、スプレッド演算子 (*) を使用します。スプレッド演算子は、配列の各要素を個別の引数として、選択した関数に渡します:

kotlin
fun main() {
    val lettersArray = arrayOf("c", "d")
    printAllStrings("a", "b", *lettersArray)
    // abcd
}

fun printAllStrings(vararg strings: String) {
    for (string in strings) {
        print(string)
    }
}

詳細については、可変長引数 (varargs) を参照してください。

コレクションへの変換

配列を使用するものとコレクションを使用するものが混在する異なる API を使用する場合、配列をコレクションに、またはその逆に変換できます。そのために、.toList().toSet()、および .toMap() 関数を使用します。 これらの関数は、配列の内容を独立したコピーにコピーします。これらは配列へのその後の変更を反映しません。

List または Set への変換

配列を List または Set に変換するには、.toList() および .toSet() 関数を使用します:

kotlin
fun main() {
    val simpleArray = arrayOf("a", "b", "c", "c")

    // Set に変換します
    println(simpleArray.toSet())
    // [a, b, c]

    // List に変換します
    println(simpleArray.toList())
    // [a, b, c, c]
}

元の配列が変更されたり他で共有されたりしないことが完全に確実でない限り、.asList() および関連する as* 関数を使用しないでください。これらの関数は、配列をコピーするのではなくラップします。したがって、配列への変更はリストに反映され、その逆も同様です。

kotlin
fun main() {
    val simpleArray = arrayOf("a", "b", "c")

    val list = simpleArray.asList()
    simpleArray[0] = "d"
    println(list)
    // [d, b, c]
}

Map への変換

配列を Map に変換するには、.toMap() 関数を使用します。

Pair<K,V> の配列のみを Map に変換できます。 Pair インスタンスの最初の値がキーになり、2番目の値が値になります。 同じキーが複数回出現する場合、最後の値が使用されます。

この例では、中置表記法 (infix notation) を使用して .to 関数を呼び出し、Pair のタプルを作成しています:

kotlin
fun main() {
    val pairArray = arrayOf("apple" to 120, "banana" to 150, "cherry" to 90, "apple" to 140)

    // Map に変換します
    // フルーツがキー、カロリー数が値です
    // 最新の "apple" の値が最初の値を上書きします
    println(pairArray.toMap())
    // {apple=140, banana=150, cherry=90}
}

次のステップ