E blokk · Tömbök, listák, Dictionary · 4. tananyag
A tömb mérete létrehozáskor eldől. Sok feladatnál viszont előre nem
tudjuk, hány elem lesz: a
C7-es
pizzafutár-kasszánál addig jöttek a tételek, amíg a felhasználó
0-t nem írt. Erre való a List<T>:
menet közben bővíthető és szűkíthető, közben ugyanúgy indexelhető, mint
a tömb. Az A2-ben
említett generikusok is itt kerülnek elő.
List<T>-t,
és tudod, mit jelent a csúcsos zárójelben álló típus.Add,
Insert), törölsz
(Remove, RemoveAt,
Clear) és keresel
(Contains, IndexOf).Count-tal
kérdezed le (nem Length!).List<string> bevasarlas = new List<string>(); // üres lista List<int> jegyek = new List<int> { 5, 4, 3 }; // kezdőelemekkel
<T> a lista
elemtípusa: List<int>
egészek listája, List<string>
szövegeké, List<double> tört
számoké. A T helyére bármely típus
írható.List
egyszer van megírva, és bármilyen elemtípussal használható — a fordító
közben ellenőrzi, hogy csak megfelelő típusú elem kerülhessen
bele.List a
System.Collections.Generic névtérben van.
Az új .NET projektekben ezt nem kell using-gal
importálni, mert a projekt alapértelmezetten elérhetővé teszi
(implicit using).List<string> bevasarlas = new List<string>(); bevasarlas.Add("kenyér"); // a lista végére bevasarlas.Add("tej"); bevasarlas.Add("alma"); bevasarlas.Insert(0, "kávé"); // a 0. helyre, a többi hátrébb csúszik Console.WriteLine(bevasarlas.Count); // 4 Console.WriteLine(bevasarlas[0]); // kávé bevasarlas[2] = "kakaó"; // a "tej" helyére Console.WriteLine(string.Join(", ", bevasarlas)); // kávé, kenyér, kakaó, alma
Add a lista végére tesz
egy elemet — ez a leggyakoribb művelet.Insert(index, elem) a
megadott helyre szúr be; a mögötte állók egy hellyel hátrébb
kerülnek.Count - 1-ig. A határon kívül itt
ArgumentOutOfRangeException keletkezik —
ugyanaz a hiba, mint az E3-ban, csak
más névvel.A lista méretének neve Count,
a tömbé Length. Ez a különbség kezdetben sok
hibát okoz — a fordító szerencsére jelzi (CS1061).
List<string> bevasarlas = new List<string> { "kávé", "kenyér", "tej", "kenyér" }; bool sikerult = bevasarlas.Remove("kenyér"); // az ELSŐ "kenyér" törlése → true bevasarlas.RemoveAt(0); // a 0. elem ("kávé") törlése Console.WriteLine(string.Join(", ", bevasarlas)); // tej, kenyér Console.WriteLine(bevasarlas.Contains("tej")); // True Console.WriteLine(bevasarlas.IndexOf("alma")); // -1 — nincs benne bevasarlas.Clear(); // minden elem törlése Console.WriteLine(bevasarlas.Count); // 0
| Metódus | Mit csinál? | Mit ad vissza? |
|---|---|---|
Remove(elem) | törli az elem első előfordulását | true, ha talált és törölt; false, ha nem volt benne |
RemoveAt(index) | törli a megadott helyen álló elemet | semmit (void) |
Clear() | kiüríti a listát | semmit |
Contains(elem) | benne van-e az elem | bool |
IndexOf(elem) | hol van az elem első előfordulása | az indexet, vagy -1, ha nincs benne |
A Contains az
E2-es
eldöntés, az IndexOf a
keresés tétele — a lista készen adja őket. Rendezéshez
és megfordításhoz a Sort() és a
Reverse() metódus használható.
A bejárás ugyanúgy megy, mint a tömbnél, csak
Length helyett
Count:
for (int i = 0; i < bevasarlas.Count; i++) { Console.WriteLine($"{i + 1}. {bevasarlas[i]}"); }
foreach (string tetel in bevasarlas) { Console.WriteLine(tetel); }
Ha a foreach törzsében
Add-ot vagy Remove-ot
hívsz, a program InvalidOperationException
kivétellel leáll („Collection was modified”).
Ha feltétel szerint kell törölni, használj visszafelé haladó
for-t:
for (int i = jegyek.Count - 1; i >= 0; i--) { if (jegyek[i] == 1) { jegyek.RemoveAt(i); } }
Miért visszafelé? Előrefelé haladva a törölt elem helyére becsúszik a következő, és a ciklus azt átugorja. Hátulról haladva a törlés csak a már feldolgozott elemek helyét érinti.
| Szempont | Tömb (int[]) | Lista (List<int>) |
|---|---|---|
| méret | létrehozáskor rögzül | menet közben változik |
| méret lekérdezése | Length | Count |
| bővítés, törlés | nem lehetséges | Add, Insert, Remove, RemoveAt |
| keresés | saját ciklussal (E2) | Contains, IndexOf |
| mikor válaszd? | ismert, fix darabszám (a hét napjai, 12 hónap, egy tábla sorai) | ismeretlen vagy változó darabszám (rendelés tételei, bekért adatok) |
A listát metódusnak ugyanúgy átadhatod, mint a tömböt, és ugyanúgy referencia: a metódus módosíthatja a hívó listáját (E2).
Előre ismert és fix az elemek száma — vagy menet közben változik?
| Tünet | Mi történt? | Mit tegyél? |
|---|---|---|
CS1061: 'List<int>' does not contain a definition for 'Length' | tömbös szokásból Length-et írtál | listánál Count |
CS1503 az Add sorában | rossz típusú elemet adtál hozzá (pl. List<int>-be szöveget) | az elem típusa egyezzen a <T>-vel |
InvalidOperationException: Collection was modified | a foreach törzsében módosítottad a listát | feltételes törléshez visszafelé haladó for |
| feltételes törlés után egy elem bennmarad | előrefelé haladó for + RemoveAt — az elem átugrik | visszafelé haladj: for (int i = Count - 1; i >= 0; i--) |
ArgumentOutOfRangeException | a lista határán kívüli index | 0 … Count - 1; előbb ellenőrizd |
a Remove „nem működik” | az elem nincs a listában (pl. más kis-nagybetűvel) | a visszatérési értéke megmondja: false = nem talált |
CS0165: Use of unassigned local variable az Add-nál | a listát deklaráltad, de nem hoztad létre | = new List<string>(); |
Bevasarlolista, .NET 10 +
Konzol.cs.List<string>
listát.Bevasarlolista: List<T> menuvel.A lista tetszőleges hosszúra bővíthető; a duplikátum nem kerül be; mindkét törlés működik, és egyik sem címez túl; üres listánál a kiírás jelzi, hogy a lista üres.
⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás
Kérj be neveket, amíg a felhasználó üres sort nem ad, majd írd ki, hány nevet adott meg, és a neveket vesszővel elválasztva.
Hozz létre egy listát 10 számmal, töröld belőle az első és az utolsó elemet, és írd ki a maradékot.
Kérj be számokat 0-ig (a 0 ne kerüljön be), majd írd ki az összegüket, az átlagukat és a legnagyobbat — a programozási tételekkel, listán.
Egy lista tartalmazza az osztály jegyeit. Töröld belőle az összes egyest, és írd ki, hány egyes volt.
Írj List<int> Kozos(List<int> a, List<int> b)
metódust, amely azokat a számokat adja vissza, amelyek mindkét
listában szerepelnek — mindegyiket csak egyszer.
Minden kérdésnél egy válasz helyes. A végén pontszámot kapsz.
| Fogalom | Jelentés |
|---|---|
List<T> | menet közben bővíthető és szűkíthető, indexelhető gyűjtemény |
| generikus típus | típussal paraméterezett típus — a <T> helyére írod az elemtípust |
Count | a lista aktuális elemszáma |
Add / Insert | elem hozzáadása a végére / a megadott helyre |
Remove / RemoveAt | elem törlése érték szerint (első előfordulás) / index szerint |
Contains / IndexOf | benne van-e / hol van (−1, ha nincs) |
| implicit using | a projekt által alapértelmezetten elérhetővé tett névterek (pl. System.Collections.Generic) |
List<T>
bővíthető gyűjtemény; a <T> az
elemtípus — a generikusok gyakorlati haszna.Add,
Insert; törlés:
Remove, RemoveAt,
Clear; keresés:
Contains, IndexOf.Count, az
indexelés 0-tól Count - 1-ig — mint a
tömbnél.foreach közben nem módosítható a lista;
feltételes törléshez visszafelé haladó for
kell.Dictionary.