Collection adalah struktur data yang menampung banyak elemen dalam satu variabel, sedangkan generic berarti tipe elemennya ditetapkan lewat parameter tipe sehingga ketidakcocokan tipe terdeteksi pada saat kompilasi. Topik ini membahas tiga collection dasar .NET, yaitu List<T> untuk data berurutan, Dictionary<K,V> untuk pencarian berdasarkan kunci, dan HashSet<T> untuk elemen yang unik. Setiap collection disertai contoh yang benar-benar dijalankan, kemudian ditutup dengan panduan memilih di antara ketiganya.
List untuk data berurutan#
List<T> menyimpan elemen dengan urutan yang dijaga dan mengizinkan akses langsung ke posisi tertentu melalui indeks. Elemen baru ditambahkan dengan metode Add, jumlahnya dibaca dari property Count, dan elemen tertentu diakses lewat penanda indeks. Indeks dimulai dari 0, sedangkan penanda ^1 menunjuk elemen dari akhir. Metode Remove menghapus elemen pertama yang nilainya cocok dengan argumennya. Contoh berikut menunjukkan operasi dasar tersebut pada daftar nilai ujian.
// Contoh: List menyimpan nilai ujian dengan urutan terjaga
List<int> nilaiUjian = new() { 84, 71, 90 };
nilaiUjian.Add(66);
Console.WriteLine($"Jumlah nilai: {nilaiUjian.Count}");
Console.WriteLine($"Nilai pertama: {nilaiUjian[0]}");
Console.WriteLine($"Nilai terakhir: {nilaiUjian[^1]}");
nilaiUjian.Remove(71);
Console.WriteLine($"Setelah Remove(71): {string.Join(", ", nilaiUjian)}");Jumlah nilai: 4
Nilai pertama: 84
Nilai terakhir: 66
Setelah Remove(71): 84, 90, 66Nilai Count berubah dari 3 menjadi 4 setelah Add(66) dijalankan, sehingga kapasitas penyimpanan bertambah secara otomatis tanpa dikelola secara manual. Penanda [^1] menghasilkan 66 karena elemen itu menempati posisi terakhir, sedangkan [0] tetap menghasilkan 84 karena posisi awalnya tidak berubah. Metode Remove(71) menghapus satu elemen bernilai 71, dan elemen di belakangnya bergeser mengisi posisi yang kosong. List<T> mengizinkan duplikat, sehingga dua elemen dengan nilai yang sama tetap tersimpan berdua.
Selain Add dan Remove, metode yang sering digunakan mencakup Insert untuk menyisipkan elemen pada posisi tertentu, Clear untuk mengosongkan seluruh isi, dan Contains untuk memeriksa keberadaan nilai. Penelusuran lewat foreach menampilkan elemen menurut urutannya, sehingga daftar nilai ujian tetap terbaca dari yang pertama sampai yang terakhir. Seluruh operasi ini bekerja di atas array internal yang dikelola List secara otomatis, sehingga kapasitasnya menyesuaikan diri tanpa campur tangan.
Dictionary untuk pencarian berdasarkan kunci#
Dictionary<K,V> menyimpan pasangan kunci dan nilai, kemudian mengambil nilai berdasarkan kuncinya tanpa menelusuri seluruh isi. Kunci harus unik, sedangkan nilai boleh sama antarpasangan. Penugasan lewat penanda indeks menambahkan pasangan baru ketika kunci belum ada dan mengganti nilai ketika kuncinya sudah terdaftar. Contoh berikut menggunakan dictionary untuk memetakan hari piket ke nama petugas.
// Contoh: Dictionary memetakan hari piket ke nama petugas
Dictionary<string, string> jadwalPiket = new()
{
["Senin"] = "Ali",
["Selasa"] = "Budi",
["Rabu"] = "Citra"
};
jadwalPiket["Kamis"] = "Dewi";
Console.WriteLine($"Piket Rabu: {jadwalPiket["Rabu"]}");
if (jadwalPiket.TryGetValue("Jumat", out string? petugas))
{
Console.WriteLine($"Piket Jumat: {petugas}");
}
else
{
Console.WriteLine("Jumat belum memiliki petugas piket");
}Piket Rabu: Citra
Jumat belum memiliki petugas piketMetode TryGetValue mengembalikan true ketika kunci ditemukan dan menampung nilainya pada variabel keluaran petugas, serta mengembalikan false tanpa melempar exception ketika kunci tidak ada. Pola inilah yang disarankan untuk kunci yang keberadaannya belum pasti, karena akses lewat penanda indeks berperilaku sebaliknya.
Perilaku pada peringatan di atas terlihat pada contoh berikut. Exception ditangkap dengan try-catch, kemudian pesan aslinya dicetak.
// Contoh: akses indexer Dictionary dengan kunci yang belum terdaftar
Dictionary<string, string> jadwalPiket = new() { ["Senin"] = "Ali" };
try
{
Console.WriteLine(jadwalPiket["Jumat"]);
}
catch (KeyNotFoundException ex)
{
Console.WriteLine(ex.Message);
}The given key 'Jumat' was not present in the dictionary.Dictionary juga dapat ditelusuri dengan foreach, dan setiap elemennya bertipe KeyValuePair<K,V> yang membawa property Key serta Value. Penelusuran seperti itu berguna untuk menampilkan seluruh isi jadwal piket tanpa mengetahui kuncinya lebih dahulu. Perlu diingat bahwa urutan pasangan pada Dictionary tidak dijanjikan mengikuti waktu penyisipannya, sehingga tampilan yang menuntut urutan tetap diurutkan secara eksplisit.
HashSet untuk elemen yang unik#
HashSet<T> menyimpan setiap nilai paling banyak satu kali, sehingga cocok untuk data yang tidak boleh berduplikat seperti daftar hadir. Metode Add mengembalikan true ketika nilai benar-benar ditambahkan dan false ketika nilainya sudah ada, sehingga keberhasilan penambahan dapat diperiksa tanpa pemeriksaan tambahan. Contoh berikut menunjukkan perilaku tersebut.
// Contoh: HashSet menolak duplikat secara diam-diam
HashSet<string> pesertaHadir = new() { "Ali", "Budi", "Citra" };
Console.WriteLine($"Tambah Budi lagi: {pesertaHadir.Add("Budi")}");
Console.WriteLine($"Tambah Dewi: {pesertaHadir.Add("Dewi")}");
Console.WriteLine($"Jumlah peserta unik: {pesertaHadir.Count}");Tambah Budi lagi: False
Tambah Dewi: True
Jumlah peserta unik: 4Pemanggilan Add("Budi") yang kedua mengembalikan false dan isi collection tidak berubah, sedangkan Add("Dewi") mengembalikan true karena Dewi belum terdaftar. Metode Contains pada HashSet<T> juga berjalan cepat karena pencariannya diarahkan oleh nilai hash, yaitu penanda numerik yang dihitung dari setiap elemen, sedangkan Contains pada List<T> menelusuri elemen satu per satu.
Memilih collection yang sesuai#
Tabel berikut merangkum kapan ketiga collection di atas dipilih.
| Kebutuhan | Pilihan | Alasan |
|---|---|---|
| Urutan penting dan akses lewat indeks | List<T> | posisi elemen dijaga dan indeks tersedia |
| Pencarian cepat berdasarkan kunci | Dictionary<K,V> | nilai diambil langsung dari kuncinya |
| Keunikan nilai dan pemeriksaan keanggotaan | HashSet<T> | duplikat ditolak dan pencarian berbasis hash |
Pertanyaan penentuannya sederhana, yaitu bagaimana data akan diakses paling sering. Daftar nilai ujian diakses menurut posisinya, sehingga List<T> tepat. Jadwal piket diakses menurut harinya, sehingga Dictionary<K,V> tepat. Daftar hadir ditanyakan keanggotaannya, sehingga HashSet<T> tepat. Karena ketiganya mengimplementasikan antarmuka enumerasi yang sama, satu collection juga dapat menggantikan yang lain dengan perubahan kecil, tetapi pilihan yang tepat sejak awal menghindarkan konversi yang tidak perlu.
Contoh program utuh#
Program berikut merangkum ketiga collection dalam satu berkas agar perilakunya dapat dibandingkan secara langsung.
// Program contoh List, Dictionary, dan HashSet
// List<T>: urutan penting dan elemen diakses lewat indeks
List<int> nilaiUjian = new() { 84, 71, 90, 66 };
nilaiUjian.Add(77);
Console.WriteLine($"Jumlah nilai: {nilaiUjian.Count}");
Console.WriteLine($"Nilai pertama: {nilaiUjian[0]}");
Console.WriteLine($"Nilai terakhir: {nilaiUjian[^1]}");
// Dictionary<K,V>: pencarian berdasarkan kunci tanpa menelusuri seluruh isi
Dictionary<string, string> jadwalPiket = new()
{
["Senin"] = "Ali",
["Selasa"] = "Budi",
["Rabu"] = "Citra"
};
if (jadwalPiket.TryGetValue("Rabu", out string? petugas))
{
Console.WriteLine($"Piket Rabu: {petugas}");
}
Console.WriteLine($"Jumat terdaftar: {jadwalPiket.ContainsKey("Jumat")}");
// HashSet<T>: elemen unik tanpa duplikat
HashSet<string> pesertaHadir = new() { "Ali", "Budi", "Citra" };
Console.WriteLine($"Tambah Budi lagi: {pesertaHadir.Add("Budi")}");
Console.WriteLine($"Tambah Dewi: {pesertaHadir.Add("Dewi")}");
Console.WriteLine($"Jumlah peserta unik: {pesertaHadir.Count}");Jumlah nilai: 5
Nilai pertama: 84
Nilai terakhir: 77
Piket Rabu: Citra
Jumat terdaftar: False
Tambah Budi lagi: False
Tambah Dewi: True
Jumlah peserta unik: 4Jalankan program tersebut dari folder topik dengan perintah berikut.
# aktifkan .NET yang terpasang di sandbox
export DOTNET_ROOT=/home/kal/.dotnet PATH=/home/kal/.dotnet:$PATH DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1
# jalankan program contoh dari folder topik
dotnet run --file Program.csJumlah nilai: 5
Nilai pertama: 84
Nilai terakhir: 77
Piket Rabu: Citra
Jumat terdaftar: False
Tambah Budi lagi: False
Tambah Dewi: True
Jumlah peserta unik: 4Kesalahan umum#
- Membaca nilai
Dictionarylewat penanda indeks untuk kunci yang belum pasti terdaftar. ExceptionKeyNotFoundExceptionmuncul pada runtime, dan perbaikannya adalah menggunakanTryGetValuesebelum akses dilakukan. - Mengira
HashSetmenjaga urutan penyisipan. Urutan penelusurannya tidak dijanjikan, sehingga kebutuhan urutan sebaiknya dilayaniList<T>atau pengurutan eksplisit. - Menambah atau menghapus elemen collection ketika
foreachsedang menelusurinya. ExceptionInvalidOperationExceptionmuncul pada runtime, dan perbaikannya adalah menelusuri salinannya terlebih dahulu, misalnya denganToList().
Ringkasan#
List<T>menjaga urutan elemen, mendukung akses lewat indeks, dan mengizinkan duplikat.Dictionary<K,V>memetakan kunci yang unik ke nilai, danTryGetValuelebih aman daripada penanda indeks untuk kunci yang belum pasti.HashSet<T>menampung setiap nilai satu kali, mengembalikanfalsedariAdduntuk duplikat, dan cepat untuk pemeriksaan keanggotaan.- Pilihan collection mengikuti pola akses data, yaitu urutan, kunci, atau keunikan.
Referensi#
- Collections — Microsoft Learn — Ikhtisar collection .NET beserta kelompok tipe dan kriteria pemilihannya.
- Dictionary<TKey,TValue> — Microsoft Learn
— Rujukan API
Dictionary<K,V>, termasuk perilakuTryGetValuedanKeyNotFoundException. - HashSet
— Microsoft Learn — Rujukan APIHashSet<T>, termasuk nilai kembali metodeAdd.