Array<T> adalah struktur dengan ukuran tetap yang menyimpan elemen bertipe T. Berbeda dengan List yang ukurannya bisa berubah, Array tidak bisa ditambah atau dikurangi jumlah elemennya setelah dibuat. Yang bisa diubah hanyalah nilai pada indeks yang sudah ada. Pada chapter ini kita akan belajar membuat Array, mengakses elemennya, dan memahami kapan Array lebih tepat dipilih daripada List.

Membuat Array #

Ada beberapa cara membuat Array di Kotlin:

kotlin Contoh: deklarasi Array
val angka: Array<Int> = arrayOf(1, 2, 3)
val buah = arrayOf("Apel", "Jeruk")             // Array<String>
val campuran: Array<Any> = arrayOf("Budi", 25)
val kuadrat = Array(5) { i -> i * i }            // [0, 1, 4, 9, 16]
val kosong: Array<String?> = arrayOfNulls(3)     // [null, null, null]

arrayOf(...) adalah cara paling umum. Array(size) { init } berguna ketika kita ingin mengisi setiap indeks berdasarkan posisinya melalui lambda. arrayOfNulls(n) membuat array berisi n elemen null bertipe nullable.

Karakteristik Utama #

KarakteristikArray<T>List<T>
UkuranTetap, tidak bisa berubahBisa berubah (mutable variant)
ElemenBisa dimodifikasi melalui indeksTergantung tipe: read-only vs mutable
Tipe elemenSelalu objek (boxed)Primitif atau objek
Operator[i], size[i], size, plus banyak operator lain
Interop JavaT[] aslijava.util.List

Array<Int> menyimpan elemen sebagai objek Integer (boxed), bukan int primitif. Untuk performa tinggi, gunakan array primitif yang akan kita bahas di chapter berikutnya.

Akses dan Modifikasi Elemen #

Akses elemen menggunakan arr[i], sama seperti List. Pengubahan elemen dilakukan melalui penugasan subscript arr[i] = x. Karena elemen mutable tetapi ukuran tetap, kita dapat mengganti nilai tetapi tidak dapat menambah atau menghapus elemen.

kotlin Contoh: akses Array
val arr = arrayOf(1, 2, 3)
arr[0] = 100        // diperbolehkan
// arr.add(4)       // tidak ada metode add
// arr.size = 5     // tidak bisa mengubah size
println(arr.size)   // tetap 3

Contoh Lengkap #

kotlin
fun main() {
    // Membuat Array
    val angka: Array<Int> = arrayOf(1, 2, 3, 4, 5)
    println("Array: ${angka.toList()}")

    // Tipe elemen disimpulkan
    val buah = arrayOf("Apel", "Jeruk", "Pisang")
    println("Buah: ${buah.toList()}")

    // Array tipe campuran
    val campuran: Array<Any> = arrayOf("Budi", 25, 1.75, true)
    println("Campuran: ${campuran.toList()}")

    // Array dengan ukuran tetap dan inisialisasi lambda
    val kotak = Array(5) { i -> i * i }
    println("Kuadrat 0..4: ${kotak.toList()}")

    // Array of nulls
    val kosong: Array<String?> = arrayOfNulls(3)
    println("Array null: ${kosong.toList()}")

    // Akses dan modifikasi elemen
    println("angka[0]: ${angka[0]}")
    angka[0] = 100
    println("Setelah angka[0] = 100: ${angka.toList()}")

    // size tetap
    println("Size: ${angka.size}")

    // Iterasi
    print("For-each: ")
    for (x in angka) print("$x ")
    println()

    // withIndex
    println("Dengan indeks:")
    for ((i, v) in angka.withIndex()) {
        println("  indeks $i = $v")
    }

    // Array<String> vs Array<Int> - elemen bertipe objek (boxed)
    val dariList = listOf(1, 2, 3).toTypedArray()
    println("Dari list: ${dariList.toList()}")

    // Konversi ke list
    val keList: List<Int> = angka.toList()
    println("Konversi ke List: $keList")

    // Array<T> tidak bisa di-resize, tapi elemennya mutable
    println("Elemen bisa diubah: ${angka[0] == 100}")
}

Output yang Dihasilkan:

text
Array: [1, 2, 3, 4, 5]
Buah: [Apel, Jeruk, Pisang]
Campuran: [Budi, 25, 1.75, true]
Kuadrat 0..4: [0, 1, 4, 9, 16]
Array null: [null, null, null]
angka[0]: 1
Setelah angka[0] = 100: [100, 2, 3, 4, 5]
Size: 5
For-each: 100 2 3 4 5 
Dengan indeks:
  indeks 0 = 100
  indeks 1 = 2
  indeks 2 = 3
  indeks 3 = 4
  indeks 4 = 5
Dari list: [1, 2, 3]
Konversi ke List: [100, 2, 3, 4, 5]
Elemen bisa diubah: true

Mari kita bedah baris-baris penting di atas:

  1. Array(5) { i -> i * i }: lambda menerima indeks dan mengembalikan nilai awal. Hasilnya [0, 1, 4, 9, 16]. Pola ini efisien karena tidak membuat list sementara.
  2. arrayOfNulls(3): membuat Array<String?> berisi tiga elemen null. Karena elemen default tidak ada untuk tipe objek, kita harus secara eksplisit mengisi atau memilih nullable.
  3. angka[0] = 100: pengubahan elemen melalui subscript. Tidak mengubah ukuran array — hanya mengganti nilai pada indeks yang ada.
  4. angka.size: properti size adalah val; tidak ada setter sehingga ukuran tidak bisa diubah. Bandingkan dengan MutableList di mana add dan remove mengubah ukuran.
  5. listOf(1,2,3).toTypedArray(): konversi List<Int> menjadi Array<Int>. Berguna ketika kita perlu memanggil API Java yang menerima array.

Kapan Memilih Array #

Array cocok dipilih ketika:

  • Memanggil API Java yang menerima T[] — misalnya varargs Java.
  • Ukuran benar-benar tetap dan diketahui sebelumnya, misalnya matriks 3x3 atau koordinat RGB.
  • Bekerja dengan kode yang sangat sensitif performa pada elemen primitif (gunakan IntArray dll.).

Referensi Lanjutan #

Setelah memahami Array<T>, kita akan melihat kelas-kelas khusus untuk tipe primitif yang menghindari overhead boxing.