Menu

List C#: Add, Remove, Contains, Find dan Sort

List<T> adalah array yang bisa bertambah panjang di C#. Pelajari cara membuat list, menambah dan menyisipkan item, menghapus berdasarkan nilai, indeks atau kondisi, mencari dengan Contains dan Find, mengurutkan berdasarkan property, dan menghindari error karena mengubah list di dalam foreach.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

List<T> adalah koleksi berurutan yang bertambah dan berkurang seiring kamu menambah dan menghapus item. Koleksi ini ada di System.Collections.Generic, diakses lewat indeks seperti array (list[0]), dan menjadi pilihan default untuk "sekumpulan benda" di C#.

Membuat list dan menambahkan item

Parameter tipe di dalam kurung sudut menyatakan apa isi list-nya: List<string>, List<int>, List<Order>.

Output:

2
Zoe, Ana, Ben, Chloe, Dev
Ana
Ana B.
3

Count adalah property, bukan method (array memakai Length, LINQ punya method Count(); pada list, pakai property-nya). Insert menggeser setiap item sesudahnya satu tempat, jadi menyisipkan di depan list yang besar butuh waktu sebanding dengan ukurannya. Add di akhir adalah operasi yang murah.

Menghapus item

Ada empat cara menghapus, tergantung apa yang kamu ketahui tentang item tersebut:

Output:

True: 85, 62, 40, 91, 55
False
62, 40, 91, 55
2 removed: 62, 91
Caught ArgumentOutOfRangeException
0

Remove menerima sebuah nilai dan hanya menghapus kecocokan pertama. Untuk menghapus semua salinan sebuah nilai, pakai RemoveAll(s => s == 40). Indeks yang salah pada list melempar ArgumentOutOfRangeException (sedangkan array melempar IndexOutOfRangeException), baik untuk list[i] maupun RemoveAt(i). RemoveRange(index, count) menghapus satu blok item.

Count vs Capacity

List menyimpan item-itemnya di sebuah array internal. Capacity adalah ukuran array itu; Count adalah berapa banyak slot yang terpakai. Saat Count mencapai Capacity, Add berikutnya mengalokasikan array yang dua kali lebih besar lalu menyalin semuanya.

Output:

Count 0, Capacity 0
Count 1, Capacity 4
Count 2, Capacity 4
Count 3, Capacity 4
Count 4, Capacity 4
Count 5, Capacity 8
Count 6, Capacity 8
Count 7, Capacity 8
Count 8, Capacity 8
Count 9, Capacity 16
Count 0, Capacity 1000

Penggandaan ini berarti sebagian besar pemanggilan Add hanya menulis ke slot yang masih kosong. Kalau kamu kira-kira tahu berapa banyak item yang akan datang, kirim angkanya ke constructor untuk melewati penyalinan di tengah jalan. Perhatikan bahwa new List<int>(1000) tetap punya Count 0: list[0] padanya akan melempar exception. Capacity adalah ruang, bukan item.

Mencari: Contains, IndexOf, Find, Exists

Output:

True
2
-1
32.00
2 cheap items
False
2
True
False

Find mengembalikan kecocokan pertama, atau nilai default tipe tersebut (null untuk class) saat tidak ada yang cocok, jadi periksa dulu sebelum memakai hasilnya. Baris terakhir mencetak False karena Contains memakai Equals, dan class tanpa override Equals membandingkan referensi: Product baru dengan field yang sama adalah objek yang berbeda. Cari berdasarkan property dengan Exists atau Find sebagai gantinya, atau override Equals dan GetHashCode pada class itu.

Semua method ini menelusuri list dari awal, jadi setiap pemanggilan bernilai O(n). Untuk pencarian berulang berdasarkan key, Dictionary menjawab dalam waktu konstan.

Mengurutkan list

Sort() mengurutkan list itu sendiri berdasarkan urutan alami item-itemnya. Kirim lambda perbandingan untuk mengurutkan berdasarkan hal lain.

Output:

1, 2, 5, 9
9, 5, 2, 1
Ben 95, Ana 120, Chloe 150
Chloe 150, Ben 95, Ana 120
Ben 95, Ana 120, Chloe 150

Sebuah perbandingan mengembalikan angka negatif saat a harus berada di depan, positif saat b yang harus di depan, dan nol saat keduanya setara; CompareTo menghasilkan persis itu. Ada dua perbedaan antara Sort dan OrderBy milik LINQ yang penting dalam praktik:

  • Sort mengubah list-nya; OrderBy mengembalikan urutan baru dan tidak mengubah list.
  • Sort tidak stabil: item yang dianggap sama bisa bertukar tempat. OrderBy stabil, dan ThenBy menambahkan key kedua: players.OrderBy(p => p.Score).ThenBy(p => p.Name).

Memanggil Sort() pada list berisi class buatanmu tanpa perbandingan akan melempar InvalidOperationException, karena list tidak tahu cara mengurutkan item-itemnya. Kirim sebuah perbandingan atau implementasikan IComparable<T> pada class tersebut.

Reverse() membalik urutan list itu sendiri. Karena System.Linq juga mendefinisikan extension Reverse, list.Reverse() pada List<T> memilih versi yang mengubah list itu sendiri, yang tidak mengembalikan apa pun.

Perulangan, dan menghapus saat iterasi

foreach membaca setiap item secara berurutan. Perulangan for juga memberimu indeksnya. Yang tidak bisa kamu lakukan adalah menambah atau menghapus item di tengah foreach pada list yang sama:

Output:

Caught InvalidOperationException
120, 80, 60
120, 80, 60

Exception-nya adalah InvalidOperationException dengan pesan "Collection was modified; enumeration operation may not execute." Perulangan for yang maju tidak melempar exception, tapi diam-diam melewatkan item tepat setelah setiap item yang kamu hapus, karena semuanya bergeser turun satu indeks. Perulangan mundur menghindari masalah itu. Solusi ketiga adalah melakukan iterasi pada salinannya: foreach (var t in orders.ToList()).

Mengubah sebuah property item di dalam foreach (misalnya order.Status = "sent") tidak masalah. Menambah atau menghapus item merusak enumerator, begitu juga mengganti item lewat indexer (orders[i] = 0).

Konversi antara list dan array

Output:

4
3
4, 4, 4, 4
Oslo / Lima / Pune / Kyiv

Kedua arah menyalin elemen ke penyimpanan baru, jadi mengubah list nantinya tidak memengaruhi array-nya. ConvertAll adalah versi milik list sendiri dari Select(...).ToList() di LINQ. Mencetak list dengan Console.WriteLine(list) menampilkan nama tipenya (System.Collections.Generic.List`1[System.String]); pakai string.Join.

Referensi singkat

TugasKode
Membuatvar l = new List<int>(); atau new List<int> { 1, 2 }
Menambah di akhirl.Add(x), l.AddRange(items)
Menyisipkan di sebuah posisil.Insert(i, x)
Menghapus kecocokan pertamal.Remove(x) (mengembalikan bool)
Menghapus berdasarkan indeksl.RemoveAt(i)
Menghapus berdasarkan kondisil.RemoveAll(x => ...) (mengembalikan jumlah)
Jumlah iteml.Count
Memeriksa isil.Contains(x), l.Exists(x => ...)
Mencaril.Find(...), l.FindAll(...), l.FindIndex(...)
Mengurutkan list itu sendiril.Sort(), l.Sort((a, b) => ...)
Salinan terurutl.OrderBy(x => ...).ToList()
Menjadi arrayl.ToArray()

Kesalahan yang sering terjadi

  • Menghapus di dalam foreach. Melempar InvalidOperationException; pakai RemoveAll atau perulangan for mundur.
  • Mengira Remove(x) menghapus setiap salinan. Method ini menghapus yang pertama; pakai RemoveAll.
  • Memakai Contains pada objek tanpa Equals. Yang dibandingkan adalah referensi; cari berdasarkan property dengan Exists.
  • Mengakses indeks pada list yang dibuat dengan capacity. new List<int>(10) masih kosong; tambahkan item dulu.
  • Mengira Sort mempertahankan urutan item yang setara. Tidak; pakai OrderBy saat urutan di antara item yang setara itu penting.
  • Memberikan list ke variabel lain untuk berbagi, lalu kaget dengan perubahannya. var copy = list; adalah list yang sama; new List<T>(list) adalah salinan.

Pertanyaan yang sering diajukan

Bagaimana cara menambahkan item ke List di C#?

list.Add(item) menambahkan satu item di akhir, list.AddRange(otherCollection) menambahkan banyak item, dan list.Insert(index, item) menaruh item di sebuah posisi lalu menggeser sisanya. Kamu juga bisa mengisi list saat membuatnya: var names = new List<string> { "Ana", "Ben" };.

Bagaimana cara menghapus item dari List di C#?

Remove(value) menghapus item pertama yang cocok dan mengembalikan true kalau item itu ditemukan. RemoveAt(index) menghapus berdasarkan posisi. RemoveAll(x => condition) menghapus setiap item yang cocok dan mengembalikan berapa banyak yang dihapus. Clear() mengosongkan list.

Bagaimana cara memeriksa apakah List berisi sebuah nilai di C#?

list.Contains(value) mengembalikan true atau false. Method ini membandingkan dengan Equals, jadi untuk class buatanmu sendiri yang dibandingkan adalah referensinya, kecuali class itu meng-override Equals. Untuk memeriksa berdasarkan sebuah property, pakai list.Exists(p => p.Name == "Ana") atau list.Any(...) dari LINQ.

Bagaimana cara mengurutkan List berdasarkan property di C#?

Kirim sebuah perbandingan ke Sort: people.Sort((a, b) => a.Age.CompareTo(b.Age)) mengurutkan list itu sendiri. Tukar a dan b untuk urutan menurun. Atau pakai LINQ, yang mengembalikan urutan baru yang sudah terurut dan mempertahankan item yang sama nilainya dalam urutan aslinya: people.OrderBy(p => p.Age).ToList().

Kenapa muncul "Collection was modified; enumeration operation may not execute"?

Kamu menambah, menghapus atau mengganti (list[i] = x) item saat sebuah foreach sedang melakukan iterasi pada list yang sama, dan enumerator melempar InvalidOperationException di langkah berikutnya. Pakai list.RemoveAll(condition), lakukan perulangan mundur dengan for, atau lakukan iterasi pada salinannya seperti list.ToList().

Apa perbedaan Count dan Capacity?

Count adalah jumlah item di dalam list. Capacity adalah ukuran array internalnya, yang paling sedikit sama dengan Count. Saat array itu penuh, list mengalokasikan array baru yang ukurannya dua kali lipat lalu menyalin item-itemnya, jadi Add rata-rata tetap cepat.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai