Masukkan Password
10 List in Dart | Dart list tutorial | Dart tutorial #9
Dari materi yang kamu kirim, video ini membahas List di Dart secara cukup lengkap: mulai dari pengertian, index, growable/fixed-length, cara membuat List, generic, constructor, mengakses elemen, iterasi, sampai const List. Materinya memang cukup panjang, jadi saya pecah menjadi bagian-bagian kecil supaya mudah dipahami.
1. Apa Itu List?
Sederhananya:
List adalah tempat untuk menyimpan banyak nilai dalam satu variable secara berurutan.
Misalnya kita ingin menyimpan 1 angka:
int number = 10;
Kalau 3 angka:
int number1 = 10;
int number2 = 20;
int number3 = 30;
Masih bisa.
Tapi bagaimana kalau ada 100 angka?
number1
number2
number3
...
number100
Tentu merepotkan.
Di sinilah List berguna.
Kita bisa melakukan:
List<int> numbers = [10, 20, 30, 40, 50];
Sekarang kelima angka tersebut berada dalam satu List.
Secara visual:
numbers
│
▼
┌────┬────┬────┬────┬────┐
│ 10 │ 20 │ 30 │ 40 │ 50 │
└────┴────┴────┴────┴────┘
0 1 2 3 4
↑ ↑
index 0 index 4
2. List Mirip Array
Kalau kamu pernah belajar:
- C
- C++
- Java
- C#
mungkin kamu mengenal istilah array.
Konsep List sangat mirip dengan array dalam hal menyimpan sekumpulan data secara berurutan dan mengaksesnya menggunakan index. Transcript juga menjelaskan List dengan analogi tersebut.
Namun jangan langsung menganggap:
ListDart = array di bahasa lain
karena List Dart memiliki API dan perilaku yang lebih kaya.
Untuk sekarang cukup ingat:
Banyak data
↓
List
3. Ciri-Ciri Utama List
Ada beberapa karakteristik List yang sangat penting.
1. Ordered
Urutan elemen dipertahankan.
var fruits = ["Apple", "Mango", "Banana"];
Urutannya:
Apple
Mango
Banana
Kalau kita masukkan Orange di posisi tertentu, posisi tersebut bisa kita tentukan.
2. Index-based
Setiap elemen memiliki index.
Index dimulai dari 0.
Element Index
Apple → 0
Mango → 1
Banana → 2
3. Duplicate diperbolehkan
List boleh memiliki nilai yang sama.
var numbers = [10, 20, 10, 30, 10];
Ini valid.
10
20
10
30
10
Tidak seperti Set, yang memiliki aturan keunikan elemen.
4. Index Dimulai dari 0
Ini adalah konsep yang sangat penting.
Misalnya:
var fruits = ["Mango", "Apple", "Banana", "Orange"];
Jangan membayangkan:
Mango → 1
Apple → 2
Banana → 3
Orange → 4
Dalam Dart:
Mango → index 0
Apple → index 1
Banana → index 2
Orange → index 3
Visual:
INDEX
↓
┌────────┬────────┬────────┬────────┐
│ Mango │ Apple │ Banana │ Orange │
└────────┴────────┴────────┴────────┘
0 1 2 3
5. Rumus Index Terakhir
Kalau jumlah elemen List adalah n, maka:
index terakhir = n - 1
Misalnya ada 5 elemen:
jumlah elemen = 5
index terakhir = 5 - 1
= 4
Jadi:
index:
0 1 2 3 4
Bukan:
0 1 2 3 5
Ini salah satu hal yang sering menyebabkan error ketika baru belajar List.
6. Mengakses Elemen List
Misalnya:
var fruits = ["Mango", "Apple", "Banana"];
Kita bisa mengambil elemen pertama:
print(fruits[0]);
Output:
Mango
Elemen kedua:
print(fruits[1]);
Output:
Apple
Elemen ketiga:
print(fruits[2]);
Output:
Banana
Jadi:
fruits[0] → Mango
fruits[1] → Apple
fruits[2] → Banana
7. Kenapa fruits[0]?
Karena angka dalam [] adalah index.
fruits[0]
dibaca secara konsep:
“Ambil elemen pada index 0 dari List
fruits.”
Jadi bukan:
“Ambil elemen nomor 0.”
Lebih tepat:
“Ambil elemen yang berada pada index 0.”
8. Mengubah Elemen List
List juga memungkinkan kita mengubah nilai sebuah elemen.
Misalnya:
var fruits = ["Mango", "Apple", "Orange"];
Kita ingin mengganti Orange menjadi Cherry.
Orange berada pada index 2.
Maka:
fruits[2] = "Cherry";
Sekarang List menjadi:
Mango
Apple
Cherry
Contoh lengkap:
void main() {
var fruits = ["Mango", "Apple", "Orange"];
fruits[2] = "Cherry";
print(fruits);
}
Output:
[Mango, Apple, Cherry]
9. Growable List vs Fixed-Length List
Ini bagian yang cukup penting dari video.
Ada dua konsep ukuran List:
List
│
├── Growable
│
└── Fixed-length
10. Apa Itu Growable List?
Growable List adalah List yang ukurannya bisa berubah.
Kita bisa:
- menambahkan elemen
- menghapus elemen
Contoh:
var fruits = ["Apple", "Mango"];
Tambahkan:
fruits.add("Banana");
Sekarang:
Apple
Mango
Banana
Hapus:
fruits.remove("Mango");
Sekarang:
Apple
Banana
Jadi ukuran List berubah:
Sebelum
[Apple, Mango]
↓
add Banana
↓
[Apple, Mango, Banana]
↓
remove Mango
↓
[Apple, Banana]
Inilah yang dimaksud growable. Transcript juga menekankan bahwa growable List dapat bertambah dan berkurang ukurannya.
11. Fixed-Length List
Kebalikannya adalah fixed-length List.
Jumlah elemennya sudah ditentukan dan tidak boleh berubah.
Misalnya:
[10, 20, 30]
Panjangnya adalah:
3
Kita tidak boleh:
list.add(40);
atau:
list.remove(20);
Tetapi ada perbedaan penting:
Fixed-length bukan berarti isi elemennya tidak boleh berubah.
Misalnya:
list[0] = 100;
bisa dilakukan pada fixed-length List yang mutable.
Jadi:
FIXED-LENGTH
│
├── jumlah elemen ❌ tidak boleh berubah
│
└── nilai elemen ✅ masih bisa berubah
Ini berbeda dengan const List, yang akan kita bahas nanti.
12. Cara Membuat Growable List
Cara yang paling sederhana adalah menggunakan List literal:
var fruits = ["Apple", "Mango", "Banana"];
List literal seperti ini biasanya menghasilkan growable List.
Kita bisa:
fruits.add("Orange");
dan:
fruits.remove("Mango");
13. Membuat Empty List
Kalau kita ingin membuat List kosong:
var items = [];
Ini adalah cara yang sangat umum.
Misalnya:
void main() {
var items = [];
items.add("Apple");
items.add("Mango");
print(items);
}
Hasil:
[Apple, Mango]
14. List.empty()
Ada cara lain:
var items = List.empty();
Nah, ini bagian yang perlu kamu perhatikan.
Secara default:
List.empty()
membuat fixed-length List.
Jadi:
var items = List.empty();
items.add("Apple");
akan menyebabkan error saat dijalankan karena List tersebut tidak growable.
Kalau ingin growable:
var items = List.empty(growable: true);
Sekarang:
items.add("Apple");
bisa dilakukan.
15. Apa Arti growable: true?
growable adalah sebuah parameter.
List.empty(growable: true)
Artinya:
“Buat List kosong yang ukurannya boleh bertambah atau berkurang.”
Sedangkan:
List.empty(growable: false)
artinya:
“Buat List kosong yang panjangnya tidak boleh berubah.”
Jadi:
List.empty()
↓
growable = false
↓
fixed-length
Sedangkan:
List.empty(growable: true)
↓
growable
Transcript menyampaikan konsep ini melalui contoh List.empty dan parameter growable.
16. Membuat List dengan Nilai Awal
Cara paling mudah:
List<int> numbers = [10, 20, 30, 40];
Atau dengan var:
var numbers = [10, 20, 30, 40];
Dart akan melakukan type inference.
Karena semua elemennya integer:
[10, 20, 30, 40]
↓
List<int>
17. Dynamic List
Transcript juga membahas List yang dapat berisi berbagai jenis nilai. Misalnya:
var values = ["Hello", 10, 20.5];
Di sini terdapat:
"Hello" → String
10 → int
20.5 → double
Artinya List tersebut tidak dibatasi hanya pada satu tipe konkret seperti List<String>.
Namun, ada hal penting:
Sebaiknya jangan sengaja menggunakan List campuran seperti ini jika sebenarnya semua data memiliki tipe yang sama.
Lebih baik:
List<String> animals = [
"Tiger",
"Dog",
"Cat"
];
daripada membuat List yang isinya campur-campur tanpa alasan.
18. Generic pada List
Sekarang kita masuk ke bagian:
List<String>
Apa arti <String>?
Itu adalah generic type.
Untuk sementara, anggap saja:
<String>memberi tahu Dart bahwa List ini hanya boleh berisi String.
Contoh:
List<String> animals = [
"Tiger",
"Dog",
"Cat"
];
Semuanya String.
Tetapi kalau:
List<String> animals = [
"Tiger",
"Dog",
10
];
❌ Error.
Karena:
List<String>
↓
harus String
tetapi:
10
↓
int
Jadi tidak cocok.
19. Generic Membantu Type Safety
Misalnya:
List<int> numbers = [10, 20, 30];
Dart sekarang mengetahui:
numbersadalah List yang elemennyaint.
Akibatnya:
numbers.add(40); // ✅
numbers.add(100); // ✅
numbers.add("Hello"); // ❌
Ini sangat berguna karena error bisa diketahui lebih awal.
Jadi generic membantu kita membuat kode lebih aman.
20. List.filled()
Sekarang masuk ke constructor yang menarik:
List.filled()
Gunanya:
Membuat List dengan jumlah elemen tertentu dan setiap elemennya diisi nilai awal yang sama.
Contoh:
var items = List.filled(5, 0);
Artinya:
5 → jumlah elemen
0 → nilai awal setiap elemen
Hasil:
[0, 0, 0, 0, 0]
21. Contoh List.filled()
var numbers = List.filled(5, 25);
print(numbers);
Output:
[25, 25, 25, 25, 25]
Jadi:
List.filled(5, 25)
│ │
│ └── nilai awal
└────── jumlah elemen
22. List.filled() Default-nya Fixed-Length
Ini penting.
var numbers = List.filled(5, 0);
List tersebut secara default fixed-length.
Jadi:
numbers.add(10);
akan menghasilkan error.
Kalau ingin growable:
var numbers = List.filled(
5,
0,
growable: true,
);
Sekarang kita bisa:
numbers.add(10);
23. List.generate()
Sekarang constructor yang lebih menarik:
List.generate()
Gunanya adalah membuat List berdasarkan sebuah fungsi generator.
Contoh:
var numbers = List.generate(
5,
(index) => index * index,
);
Hasil:
[0, 1, 4, 9, 16]
Kenapa?
Karena index dimulai dari 0:
index = 0
0 × 0 = 0
index = 1
1 × 1 = 1
index = 2
2 × 2 = 4
index = 3
3 × 3 = 9
index = 4
4 × 4 = 16
24. Memahami List.generate() dengan Diagram
List.generate(
5,
(index) => index * index,
);
Secara konsep:
List.generate
│
┌─────────┴─────────┐
│ │
jumlah = 5 generator
│
▼
index → index²
│
┌──────────────────┼───────────────┐
↓ ↓ ↓
index 0 index 1 index 2
↓ ↓ ↓
0 × 0 1 × 1 2 × 2
↓ ↓ ↓
0 1 4
Kemudian berlanjut sampai index 4.
25. Kenapa Index Generator Dimulai dari 0?
Karena List menggunakan zero-based indexing.
Kalau kita membuat:
List.generate(5, ...)
jumlah elemennya 5.
Maka index-nya:
0
1
2
3
4
Bukan:
1
2
3
4
5
26. Membuat List dari List Lain
Video kemudian membahas beberapa constructor untuk membuat List berdasarkan collection lain, terutama:
List.from()
List.of()
List.unmodifiable()
Konsep sederhananya:
List 1
│
│ salin/buat berdasarkan data
▼
List 2
Misalnya:
var list1 = ["Tiger", "Dog", "Cat"];
var list2 = List.from(list1);
print(list2);
Hasil:
[Tiger, Dog, Cat]
27. List.from()
List.from() digunakan untuk membuat List baru dari iterable/collection lain.
Contoh:
var list1 = ["Tiger", "Dog", "Cat"];
var list2 = List.from(list1);
Sekarang:
list1 → [Tiger, Dog, Cat]
list2 → [Tiger, Dog, Cat]
Yang perlu kamu pahami:
list2adalah List baru yang dibuat berdasarkan elemenlist1.
28. List.of()
List.of() memiliki tujuan yang mirip:
var list1 = ["Tiger", "Dog", "Cat"];
var list2 = List.of(list1);
Hasil:
list2 → [Tiger, Dog, Cat]
Tetapi ada perbedaan penting dalam type checking.
Secara sederhana:
List.from()
Lebih fleksibel dalam bagaimana source collection diperlakukan, dan pada bentuk tertentu type check yang lebih ketat tidak selalu terjadi secara statis.
List.of()
Lebih ketat terhadap tipe collection yang diberikan.
Misalnya:
var strings = <String>["A", "B"];
var numbers = List<int>.of(strings);
Dart dapat langsung menolak ini karena:
strings
↓
Iterable<String>
tetapi dibutuhkan
↓
Iterable<int>
Jadi List.of() lebih membantu menangkap ketidaksesuaian tipe lebih awal.
Transcript memang menekankan perbedaan static type checking antara from dan of.
29. Jangan Terlalu Fokus pada from vs of Dulu
Kalau kamu masih pemula, jangan sampai bagian ini membuat bingung.
Untuk sementara ingat:
List.from()
↓
buat List berdasarkan collection lain
List.of()
↓
buat List berdasarkan collection lain
+ type checking lebih ketat
Nanti ketika sudah belajar Generics dan Iterable, perbedaan ini akan jauh lebih mudah dipahami.
30. List.unmodifiable()
Sekarang kita masuk ke List yang tidak bisa dimodifikasi.
var list2 = List.unmodifiable(list1);
Artinya:
Buat List berdasarkan
list1, tetapi List hasilnya tidak bisa dimodifikasi.
Misalnya:
var list1 = ["Tiger", "Dog", "Cat"];
var list2 = List.unmodifiable(list1);
Kita bisa membaca:
print(list2[0]);
Tetapi tidak bisa:
list2.add("Monkey");
atau:
list2[0] = "Lion";
atau:
list2.remove("Dog");
Semua itu tidak diperbolehkan.
31. List.unmodifiable() vs const List
Ini perlu dibedakan.
Ada dua konsep yang sering dianggap sama:
Unmodifiable List
dan:
Const List
Keduanya tidak bisa dimodifikasi melalui operasi biasa, tetapi mekanismenya berbeda.
const memiliki aturan compile-time constant.
Contoh:
const fruits = ["Apple", "Mango", "Banana"];
List tersebut tidak bisa dimodifikasi.
32. const List
Contoh:
const fruits = [
"Apple",
"Mango",
"Banana",
];
Sekarang:
fruits.add("Orange");
❌ Tidak boleh.
Begitu juga:
fruits[0] = "Grape";
❌ Tidak boleh.
Dan:
fruits.remove("Apple");
❌ Tidak boleh.
Jadi:
const List
│
├── tidak bisa add
├── tidak bisa remove
├── tidak bisa mengubah elemen
└── tidak bisa memodifikasi object List tersebut
Transcript menjelaskan bagian ini sebagai immutable/constant List.
33. Tetapi Ada Hal yang Sering Disalahpahami tentang const
Misalnya:
const fruits = ["Apple", "Mango"];
Lalu:
fruits = ["Orange", "Banana"];
❌ Tidak boleh.
Karena variable fruits sendiri adalah const.
Tetapi kalau kita menggunakan:
var fruits = const ["Apple", "Mango"];
maka yang const adalah object List-nya, sedangkan variable fruits masih bisa diarahkan ke object lain.
Contoh:
var fruits = const ["Apple", "Mango"];
fruits = ["Orange", "Banana"];
Ini bisa.
Kenapa?
Karena kita bukan mengubah List const yang pertama.
Kita membuat List baru:
Awalnya:
fruits
│
▼
const ["Apple", "Mango"]
Setelah assignment:
fruits
│
▼
["Orange", "Banana"]
Object pertama tidak diubah.
Variable fruits sekarang mereferensikan object yang berbeda.
Ini adalah poin yang sangat penting dari bagian akhir transcript.
34. Bedakan “Mengubah List” dan “Mengganti Isi Variable”
Ini salah satu konsep yang sering membingungkan pemula.
Misalnya:
var fruits = const ["Apple", "Mango"];
Kita tidak boleh:
fruits[0] = "Banana";
Karena kita sedang mencoba mengubah object List.
Tetapi:
fruits = ["Banana", "Orange"];
berbeda.
Kita tidak mengubah object lama.
Kita membuat object baru lalu variable fruits diarahkan ke object baru.
Visual:
SEBELUM
fruits ───────► const ["Apple", "Mango"]
SETELAH
const ["Apple", "Mango"]
↑
│
tidak diubah
fruits ───────► ["Banana", "Orange"]
35. Cara Mengakses List dengan elementAt()
Selain:
fruits[0]
kita juga bisa menggunakan:
fruits.elementAt(0)
Contoh:
var fruits = ["Mango", "Apple", "Banana"];
print(fruits[0]);
atau:
print(fruits.elementAt(0));
Keduanya mengambil elemen pada index 0.
Hasil:
Mango
Transcript menyebut elementAt() sebagai alternatif untuk mengakses elemen berdasarkan index.
36. Iterasi List
Sekarang kita sampai pada bagian yang sangat sering digunakan dalam Flutter:
Bagaimana cara mengambil semua elemen List satu per satu?
Misalnya:
var animals = [
"Tiger",
"Dog",
"Rat",
"Cat"
];
Kita ingin mencetak semuanya.
Ada beberapa cara.
37. Cara 1 — for Loop Biasa
for (int i = 0; i < animals.length; i++) {
print(animals[i]);
}
Mari kita pahami:
i = 0
↓
animals[0]
↓
Tiger
i = 1
↓
animals[1]
↓
Dog
i = 2
↓
animals[2]
↓
Rat
i = 3
↓
animals[3]
↓
Cat
Output:
Tiger
Dog
Rat
Cat
38. Kenapa i < animals.length?
Misalnya List memiliki 4 elemen:
length = 4
Index yang valid:
0
1
2
3
Maka:
i < animals.length
berarti:
i < 4
Sehingga:
i = 0 ✅
i = 1 ✅
i = 2 ✅
i = 3 ✅
i = 4 ❌
Ini mencegah kita mengakses:
animals[4]
yang tidak ada.
39. Cara 2 — for-in
Kalau kita tidak membutuhkan index, for-in biasanya jauh lebih sederhana.
for (var animal in animals) {
print(animal);
}
Artinya:
Untuk setiap
animalyang ada di dalamanimals, lakukan sesuatu.
Visual:
animals
│
├── Tiger → animal
├── Dog → animal
├── Rat → animal
└── Cat → animal
Output:
Tiger
Dog
Rat
Cat
Ini biasanya lebih mudah dibaca daripada for biasa jika index tidak diperlukan.
40. Kapan Menggunakan for dan for-in?
Gunakan for biasa
Kalau kamu membutuhkan index:
for (int i = 0; i < animals.length; i++) {
print("$i: ${animals[i]}");
}
Hasil:
0: Tiger
1: Dog
2: Rat
3: Cat
Gunakan for-in
Kalau hanya membutuhkan value:
for (var animal in animals) {
print(animal);
}
Lebih simpel.
41. Cara 3 — forEach()
Cara ketiga adalah:
animals.forEach((animal) {
print(animal);
});
Artinya:
Jalankan function tersebut untuk setiap elemen dalam List.
Misalnya:
var animals = ["Tiger", "Dog", "Rat", "Cat"];
animals.forEach((animal) {
print(animal);
});
Hasil:
Tiger
Dog
Rat
Cat
42. Memahami forEach() dengan Sederhana
Jangan takut dengan syntax ini:
animals.forEach((animal) {
print(animal);
});
Anggap saja:
animals
↓
ambil satu elemen
↓
masukkan ke animal
↓
jalankan print
↓
ambil elemen berikutnya
↓
ulang
Jadi secara konsep:
Tiger → print
Dog → print
Rat → print
Cat → print
43. Perbandingan Tiga Cara Iterasi
| Cara | Cocok ketika |
|---|---|
for | Membutuhkan index |
for-in | Hanya membutuhkan setiap value |
forEach() | Ingin menjalankan function untuk setiap elemen |
Contoh:
// 1. for
for (int i = 0; i < animals.length; i++) {
print(animals[i]);
}
// 2. for-in
for (var animal in animals) {
print(animal);
}
// 3. forEach
animals.forEach((animal) {
print(animal);
});
Ketiganya bisa menghasilkan output yang sama.
44. Kesalahan Umum Saat Belajar List
Kesalahan 1 — Mengira index dimulai dari 1
var fruits = ["Apple", "Mango"];
print(fruits[1]);
Ini menghasilkan:
Mango
Bukan Apple.
Karena:
Apple → 0
Mango → 1
Kesalahan 2 — Mengakses index yang tidak ada
var fruits = ["Apple", "Mango"];
print(fruits[2]);
❌ Error.
Karena index valid hanya:
0
1
Kesalahan 3 — Menambahkan elemen ke fixed-length List
var numbers = List.filled(3, 0);
numbers.add(10);
❌ Error.
Karena List tersebut fixed-length.
Kesalahan 4 — Mengubah const List
const fruits = ["Apple", "Mango"];
fruits.add("Banana");
❌ Error.
Karena const List tidak dapat dimodifikasi.
45. Peta Konsep Seluruh Materi
Kalau semua isi video kita sederhanakan:
LIST
│
┌────────────────┼────────────────┐
│ │ │
Ordered Indexed Duplicate
│ │ allowed
│ │
│ index mulai 0
│
▼
┌───────────────┐
│ │
Growable Fixed-length
│ │
add/remove tidak bisa
bisa add/remove
│ │
└────────┬──────┘
│
List Creation
│
┌────────┼─────────────┐
│ │ │
[] List.empty List.filled
│
List.generate
│
List.from / List.of
│
List.unmodifiable
│
const
46. Cheat Sheet yang Sebaiknya Kamu Simpan
Membuat List
var fruits = ["Apple", "Mango", "Banana"];
List kosong
var fruits = [];
Generic
List<String> fruits = ["Apple", "Mango"];
Mengambil elemen
print(fruits[0]);
Mengubah elemen
fruits[0] = "Orange";
Menambahkan
fruits.add("Banana");
Menghapus
fruits.remove("Apple");
Panjang List
print(fruits.length);
for
for (int i = 0; i < fruits.length; i++) {
print(fruits[i]);
}
for-in
for (var fruit in fruits) {
print(fruit);
}
forEach
fruits.forEach((fruit) {
print(fruit);
});
Fixed-length
var numbers = List.filled(5, 0);
Growable
var numbers = List.filled(
5,
0,
growable: true,
);
Generate
var numbers = List.generate(
5,
(index) => index * index,
);
Hasil:
[0, 1, 4, 9, 16]
Unmodifiable
var fruits = List.unmodifiable([
"Apple",
"Mango",
]);
Const
const fruits = [
"Apple",
"Mango",
];
🎯 Inti Materi yang Harus Benar-Benar Kamu Pahami
Kalau kamu belum hafal semua constructor tadi, tidak masalah. Yang paling penting untuk tahap sekarang adalah memahami konsep berikut:
1. List = banyak value dalam satu variable
var numbers = [10, 20, 30];
2. List menggunakan index
10 → 0
20 → 1
30 → 2
3. Index dimulai dari 0
numbers[0] // 10
4. List bisa growable atau fixed-length
Growable
→ bisa add/remove
Fixed-length
→ tidak bisa mengubah jumlah elemen
5. Generic membatasi tipe elemen
List<String> names = ["Budi", "Andi"];
Artinya List tersebut ditujukan untuk String.
6. List.generate() bisa membuat data berdasarkan index
List.generate(
5,
(index) => index * index,
);
Hasil:
[0, 1, 4, 9, 16]
7. Ada beberapa cara iterasi
for (...)
for (var item in list)
list.forEach(...)
8. const List tidak bisa dimodifikasi
const numbers = [1, 2, 3];
Tidak bisa:
numbers.add(4);
numbers[0] = 100;
🧠 Satu analogi terakhir
Bayangkan List seperti rak dengan beberapa kotak:
List
↓
┌────────┬────────┬────────┬────────┐
│ Kotak 0│ Kotak 1│ Kotak 2│ Kotak 3│
│ Apple │ Mango │ Banana │ Orange │
└────────┴────────┴────────┴────────┘
Index = nomor kotak.
0 1 2 3
Growable List = kamu boleh menambah/mengurangi kotak.
Fixed-length List = jumlah kotaknya tetap.
Generic List<String> = semua kotak hanya boleh berisi String.
const List = rak beserta isinya tidak boleh kamu ubah.
Kalau analogi rak ini sudah masuk ke kepala, konsep dasar List Dart sebenarnya sudah kamu kuasai.