Koleksi adalah struktur penyimpanan yang banyaknya elemen dapat berubah saat program berjalan, dan topik ini membahas dua koleksi generik utama .NET, yaitu List(Of T) dan Dictionary(Of K, V). Pembahasan dimulai dari kelemahan array berukuran tetap dan ArrayList, dilanjutkan dengan operasi dasar kedua koleksi generik, dan ditutup dengan kesalahan yang sering terjadi. Setelah membacanya, pemilihan koleksi untuk daftar peserta, inventaris, atau pemetaan kunci ke nilai dapat dilakukan dengan alasan yang jelas.
Masalah array dan ArrayList#
Array memiliki ukuran yang ditetapkan saat dibuat dan tidak dapat bertumbuh. Deklarasi Dim stok(4) As Integer menyediakan tepat lima elemen dengan indeks 0 sampai 4, dan penambahan elemen baru menuntut pembuatan array lain yang lebih besar lalu penyalinan isinya. Bentuk ReDim mempermudah langkah itu, tetapi di baliknya tetap membuat array baru, sehingga pertumbuhan yang sering terjadi menjadi boros.
' tidak-dijalankan
Dim stok(4) As Integer ' lima elemen, indeks 0 sampai 4
stok(4) = 10
' stok(5) = 20 ' error saat berjalan: indeks berada di luar batasArrayList mengatasi masalah ukuran dengan menyimpan setiap elemen sebagai Object, tipe paling umum di .NET. Karena itu, ArrayList menerima campuran tipe apa pun dan compiler tidak dapat memeriksa kecocokan isinya. Pengambilan kembali nilai menghasilkan Object yang masih harus dikonversi, dan konversi yang keliru baru terlihat saat program berjalan.
' tidak-dijalankan
Dim antre As New ArrayList()
antre.Add("Ali")
antre.Add(30)
' antre(1) bertipe Object, sehingga konversi eksplisit diperlukan
Dim salah As String = DirectCast(antre(1), String)Kode tersebut lolos kompilasi, tetapi baris konversinya melempar System.InvalidCastException saat program berjalan dengan pesan Unable to cast object of type 'System.Int32' to type 'System.String'. Kedua masalah di atas diselesaikan oleh koleksi generik (generics), yaitu koleksi yang menerima parameter tipe sehingga isinya diperiksa compiler sejak awal.
List(Of T): daftar yang dapat bertumbuh#
List(Of T) adalah daftar yang bertumbuh otomatis dan hanya menyimpan elemen bertipe T. Tipe T dituliskan pada saat deklarasi, misalnya List(Of String) untuk teks dan List(Of Integer) untuk bilangan bulat, sehingga pemanggilan Add dengan tipe lain ditolak compiler. Banyaknya elemen dapat diketahui melalui properti Count, sedangkan elemen dibaca lewat indeks yang dimulai dari nol.
Diagram berikut membandingkan cara ArrayList dan List(Of String) menyimpan isinya.
Program berikut mengelola daftar peserta pelatihan dengan List(Of String), mulai dari penambahan, pembacaan, penghapusan, sampai penelusurannya.
Module Program
Sub Main()
Dim peserta As New List(Of String)
peserta.Add("Ali")
peserta.Add("Budi")
peserta.Add("Citra")
peserta.Add("Dewi")
Console.WriteLine($"Jumlah peserta: {peserta.Count}")
Console.WriteLine(peserta(0))
Console.WriteLine(peserta(2))
peserta.Remove("Budi")
Console.WriteLine($"Setelah Remove: {peserta.Count}")
Console.WriteLine(peserta.Contains("Citra"))
For Each nama As String In peserta
Console.WriteLine(nama)
Next
End Sub
End ModuleJumlah peserta: 4
Ali
Citra
Setelah Remove: 3
True
Ali
Citra
DewiKeluaran mengikuti urutan operasinya. Add menambah empat peserta sehingga Count melaporkan 4, lalu peserta(0) dan peserta(2) membaca elemen pertama dan ketiga. Remove("Budi") mengurangi isi menjadi 3, dan Contains("Citra") mengembalikan True karena Citra masih terdaftar. Perulangan For Each kemudian menampilkan sisa peserta, yaitu Ali, Citra, dan Dewi, dalam urutan penambahannya.
Langkah praktisnya menggunakan .NET SDK melalui perintah berikut.
# tidak-dijalankan
# membuat proyek console VB.NET baru bernama LatihanKoleksi
dotnet new console -lang VB -o LatihanKoleksi
# mengganti isi Program.vb dengan kode program di atas melalui editor
# masuk ke folder proyek
cd LatihanKoleksi
# mengompilasi dan menjalankan program
dotnet run$ dotnet new console -lang VB -o LatihanKoleksi
The template "Console App" was created successfully.
Processing post-creation actions...
Restoring /home/kal/my-project/build-scratch/koleksi-linq__transkrip/LatihanKoleksi/LatihanKoleksi.vbproj:
Determining projects to restore...
Restored /home/kal/my-project/build-scratch/koleksi-linq__transkrip/LatihanKoleksi/LatihanKoleksi.vbproj (in 76 ms).
Restore succeeded.
$ cd LatihanKoleksi
$ dotnet run
Jumlah peserta: 4
Ali
Citra
Setelah Remove: 3
True
Ali
Citra
DewiDictionary(Of K, V): peta kunci ke nilai#
Dictionary(Of K, V) menyimpan pasangan kunci dan nilai, dengan K tipe kuncinya dan V tipe nilainya. Kunci harus unik, dan pencarian berdasarkan kunci dilakukan langsung melalui tabel hash tanpa menelusuri seluruh koleksi. Untuk inventaris perpustakaan kelas, kuncinya berupa kategori buku bertipe String dan nilainya berupa jumlah salinan bertipe Integer.
Program berikut mengisi inventaris, membaca nilai lewat TryGetValue, mengubah nilai lewat akses indeks, dan menelusuri seluruh entri.
Module DemoDictionary
Sub Main()
Dim inventaris As New Dictionary(Of String, Integer)
inventaris.Add("Novel", 12)
inventaris.Add("Kamus", 3)
inventaris.Add("Atlas", 5)
Dim jumlah As Integer
If inventaris.TryGetValue("Kamus", jumlah) Then
Console.WriteLine($"Kamus: {jumlah}")
End If
inventaris("Atlas") = 7
Console.WriteLine(inventaris("Atlas"))
If inventaris.TryGetValue("Majalah", jumlah) Then
Console.WriteLine(jumlah)
Else
Console.WriteLine("Majalah tidak terdaftar")
End If
For Each entri As KeyValuePair(Of String, Integer) In inventaris
Console.WriteLine($"{entri.Key}: {entri.Value}")
Next
End Sub
End ModuleKamus: 3
7
Majalah tidak terdaftar
Novel: 12
Kamus: 3
Atlas: 7Metode TryGetValue menerima kunci beserta variabel penampung, lalu mengembalikan True bila kuncinya terdaftar dan mengisi variabel tersebut dengan nilainya. Penugasan inventaris("Atlas") = 7 memperbarui nilai kunci yang sudah ada menjadi 7, sedangkan pencarian kunci Majalah yang belum terdaftar mengembalikan False sehingga cabang Else berjalan. Perulangan For Each menyajikan setiap entri sebagai KeyValuePair(Of String, Integer), dan properti Key serta Value mengembalikan kedua bagian pasangannya.
Kesalahan umum#
Tiga kesalahan berikut paling sering muncul saat menggunakan koleksi generik. Ketiganya dapat dihindari dengan kebiasaan penulisan yang sederhana.
- Menggunakan koleksi tanpa
New. DeklarasiDim daftar As List(Of String)tanpa instansiasi menghasilkanNothing, sehingga pemanggilanAddpertama memicuNullReferenceExceptionsaat program berjalan. Perbaikannya adalah menuliskanNew List(Of String)pada deklarasi. - Menambahkan kunci yang sudah ada dengan
Add. Metode ini menolak kunci ganda dengan melemparArgumentException, sedangkan penugasaninventaris("Kamus") = 4memperbarui nilai kunci yang sudah terdaftar tanpa error. - Mengubah isi koleksi saat
For Eachsedang menelusurinya. Penambahan atau penghapusan di tengah penelusuran memicuInvalidOperationException, dan perbaikannya adalah mengumpulkan elemen yang akan dihapus pada daftar terpisah, lalu menghapusnya setelah perulangan selesai.
Ringkasan#
- Array berukuran tetap dan
ArrayListmenyimpan nilai tanpa pemeriksaan tipe yang memadai, sehingga koleksi generik menjadi pilihan utama untuk data yang bertumbuh. List(Of T)menyimpan daftar bertipe yang bertumbuh otomatis, denganAdd,Remove,Contains, akses indeks, danCountsebagai operasi utamanya.Dictionary(Of K, V)memetakan kunci unik ke nilai, danTryGetValuemenjadi cara aman untuk membaca kunci yang keberadaannya belum pasti.- Tipe pada parameter
Of Tdiperiksa compiler, sehingga kesalahan tipe tertangkap sebelum program berjalan.
Referensi#
- Generic Types in Visual Basic — Microsoft Learn — Mekanisme parameter tipe pada kelas dan struktur generik VB.
- List(Of T) Class — Microsoft Learn — Dokumentasi metode Add, Remove, Contains, dan properti Count.
- Dictionary(Of TKey, TValue) Class — Microsoft Learn — Peta kunci-nilai beserta TryGetValue, akses indeks, dan Item.
- Collections — Microsoft Learn — Ikhtisar koleksi .NET dari sudut pandang Visual Basic.