15. diel - List
V predchádzajúcej lekcii, Dátum a čas v C# - DateOnly a TimeOnly, sme si precvičili použitie
štruktúr DateOnly a TimeOnly.
Dnes si v kurze C# ukážeme jednu kolekciu, ktorá je múdrejšia ako pole. Umožňuje totiž prvky ľubovoľne pridávať a mazať.
Pojem kolekcie sme tu už spomínali. Je to štruktúra, do ktorej môžeme
ukladať viacero objektov. Kolekcií je v .NET frameworku veľké množstvo, sú
prispôsobené na rôzne účely a môžeme s nimi zaobchádzať rôznymi
spôsobmi. Preto im je venovaný aj celý kurz Kolekcie a LINQ. Doteraz poznáme iba kolekciu
poľa. V priebehu kurzu však budeme potrebovať niečo múdrejšie, kam budeme
môcť jednoducho za behu programu pridávať a mazať
záznamy. Určite by sa nám hodilo si v pamäti spravovať databázu
nejakých objektov. Vieme, že pole má konštantnú veľkosť, čo je daň za
jeho vysokú rýchlosť. Teraz si predstavíme List, ktorý
môžeme chápať ako nadstavbu poľa.
List
Zoznam (List) je tzv. generická kolekcia.
Pojem genericita
si úplne vysvetlíme až pri kolekciách, teraz nám bude stačiť vedieť, že
pri deklarácii zoznamu musíme špecifikovať dátový typ objektov, ktoré v
ňom budú uložené. Začnime jednoducho a urobme si List čísel,
ktoré budeme náhodne žrebovať.
Žrebovanie
Program sa nás vždy spýta, či chceme žrebovať ďalšie číslo a to sa
pridá do zoznamu. Pokiaľ už nebudeme chcieť žrebovať, program vypíše
žrebované čísla, zoradené od najmenšieho po najväčšie. Vytvorme si
nový projekt ListLottery a vytvorme si triedu
Lottery. Trieda bude obsahovať List typu
int, kde budú čísla uložené. List bude privátny
a bude slúžiť iba ako interné úložisko danej triedy, aby sa tam zvonku
nedalo pristupovať. List deklarujeme takto:
List<int> numbers;
Dátový typ píšeme pri generických kolekciách do špicatých
zátvoriek. List je samozrejme objekt, ako každý iný.
Rovnako ako pri poli a iných objektoch, aj tu premennú pred použitím
inicializujeme:
List<int> numbers = new List<int>();
Všimnite si zátvorku, ktorú označuje konštruktor. Takýto zoznam teda
umiestnime do našej triedy, spolu s náhodným generátorom
Random. V konštruktore atribúty inicializujeme:
class Lottery { private List<int> numbers; private Random random; public Lottery() { random = new Random(); numbers = new List<int>(); } }
Ďalej pridáme metódy Lot() a Print(), kde
Lot() pridá do zoznamu numbers nové náhodné
číslo a tiež ho vráti ako návratovú hodnotu. Print() vráti
textový reťazec na vypísanie. Ten bude obsahovať čísla z
numbers, zoradené a oddelené medzerou.
Žrebovanie náhodného čísla už poznáme z lekcie
o hracej kocke, tu budeme vyhadzovať čísla od 1 do
100. Číslo do kolekcie List pridáme pomocou metódy
Add():
public int Lot() { int number = random.Next(100) + 1; numbers.Add(number); return number; }
Veľmi jednoduché, že? Kolekcia List je interne pomerne
zložitá a zatiaľ sa nebudeme zaoberať tým, čo sa vo vnútri deje. To je
napokon účel .NET frameworku - ponúkať kvalitné a sofistikované
komponenty, ktoré sa jednoducho používajú.
Výpis čísel bude ešte jednoduchší. Na zotriedenie použijeme metódu
Sort() volanú na inštanciu zoznamu, ktorá List
zotriedi. Je podobná metóde Sort() na triede Array.
Metóda nič nevracia, iba List vo vnútri zotriedi:
public string Print() { string s = ""; numbers.Sort(); foreach (int i in numbers) s += i + " "; return s; }
Hotovo.
Presuňme sa do Main() a pomocou while cyklu
umožnime užívateľovi ovládať objekt. Podobný program bola kalkulačka z
prvých lekcií, kde sme sa v cykle pýtali, či si používateľ praje
opakovať výpočet. Tu budeme postupovať rovnako.
Ovládanie bude pomocou možností 1, 2, 3 (losuj, vypíš, koniec). Budeme
ich načítať pomocou Console.ReadKey() ako char, nie
ako string. Nezabudnite teda, že znaky zapisujeme pomocou
apostrofov, nie úvodzoviek:
Lottery lottery = new Lottery(); Console.WriteLine("Welcome to our lottery program."); char choice = '0'; // main loop while (choice != '3') { // option list Console.WriteLine("1 - Lot the next number"); Console.WriteLine("2 - Print numbers"); Console.WriteLine("3 - Quit"); choice = Console.ReadKey().KeyChar; Console.WriteLine(); // reaction to choice switch (choice) { case '1': Console.WriteLine("You got a: {0}", lottery.Lot()); break; case '2': Console.WriteLine("Numbers drawn: {0}", lottery.Print()); break; case '3': Console.WriteLine("Thanks for using our Lotto program"); break; default: Console.WriteLine("Invalid option. Please, try again."); break; } }
Priebeh programu je z kódu dobre viditeľný. Najprv nastavíme voľbu na
nejakú východiskovú hodnotu, aby cyklus prvýkrát prebehol. Potom voľbu
načítame z klávesnice ako znak. Znak spracujeme pomocou konštrukcie
switch a vykonáme príslušné akcie. Pokiaľ bolo zadané niečo
iné, pokryje to možnosť default:
Konzolová aplikácia
...
1 - Lot the next number
2 - Print numbers
3 - Quit
1
You got a: 52
1 - Lot the next number
2 - Print numbers
3 - Quit
1
You got a: 40
1 - Lot the next number
2 - Print numbers
3 - Quit
1
You got a: 62
1 - Lot the next number
2 - Print numbers
3 - Quit
2
Numbers drawn: 10 12 13 14 21 22 23 24 28 28 40 42 45 52 52 57 58 59 62 70 71 72 79 83 86 89
1 - Lot the next number
2 - Print numbers
3 - Quit
...
Vidíme, že môžeme stále pridávať nové a nové čísla. Máme oveľa väčšie možnosti ako s poľom. Zároveň však môžeme so zoznamom pracovať úplne rovnako, ako sme pracovali s poľom.
Môžeme používať indexáciu pomocou hranatých zátvoriek, ale pozor, prvok musí existovať. Skúsme si napísať nasledujúci kód:
List<string> l = new List<string>(); l.Add("First"); Console.WriteLine(l[0]); l[0] = "First item"; Console.WriteLine(l[0]); l[1] = "Second item"; // causes an error
Vytvoríme si List položiek typu string. Pridáme
položku First a potom vypíšeme položku na indexe
0. Vypíše sa nám First. Môžeme na ňu samozrejme
aj takto zapisovať. S druhou položkou na pozícii 1 však už
nemôžeme pracovať, pretože sme ju do zoznamu nepridali. Pri poli sme zadali
veľkosť a ono všetky "priehradky" (premenné pod indexy) vytvorilo. Teraz
veľkosť nezadávame a "priehradky" si pridávame sami.
Pozrime sa na List podrobnejšie a vypíšme si metódy, ktoré
sú pre nás teraz zaujímavé:
Konštruktory
Okrem prázdneho zoznamu môžeme List vytvoriť aj ako kópiu z
iného zoznamu, poľa alebo inej kolekcie. Stačí kolekciu odovzdať do
konštruktora:
{CSHARP_CONSOLE}
string[] stringArray = {"First", "Second", "Third"};
List<string> l = new List<string>(stringArray);
Console.WriteLine(l[2]);
{/CSHARP_CONSOLE}
Kód vyššie vypíše Third. Prvky poľa sa do nového zoznamu
skopírujú. Rovnako môžeme odovzdať aj iný List.
Vlastnosti kolekcie List
Count- Funguje akoLengthna poli, vracia počet prvkov v kolekcii.
Metódy kolekcie List
Add(item)- MetóduAdd()sme si už vyskúšali, ako parameter berie položku, ktorú vloží na koniec zoznamu.AddRange(collection)- Pridá do zoznamu viac položiek, napr. z poľa.Clear()- Vymaže všetky položky v zozname.Contains(item)- Vraciatrue/falsepodľa toho, čiListobsahuje odovzdanú položku.CopyTo(array)- Skopíruje položky do odovzdaného poľa. Môžeme pridať parameter štartovný index a počet prvkov.IndexOf(item)- Vráti index prvého výskytu položky (ako pri poli). Vracia-1pri neúspechu.Insert(index, item)- Vloží položku na daný index (pozíciu) v zoznamu.InsertRange(index, collection)- Vloží prvky danej kolekcie na daný index.LastIndexOf(item)- Vracia index posledného výskytu položky. Vracia-1pri neúspechu.Remove(item)- Vymaže prvú nájdenú položku.RemoveAt(index)- Vymaže položku na danom indexe.RemoveRange(index, count)- Vymaže daný počet prvkov od zadaného indexu.Reverse()- Funguje rovnako ako u poľa, obrátiListtak, že je prvá položka posledná a naopak. Metóda nič nevracia, zmeny sa vykonajú priamo v danom zoznamu.Sort()-Sort()už tiež poznáme, zotriedi položky v zozname. Metóda opäť nič nevracia.ToArray()- Skopíruje položky do poľa a to vráti.
Ďalšie metódy
List poskytuje aj ďalšie metódy, ktoré poznáme z poľa:
Average()- Vráti priemer z položiek akodouble.Distinct()- Vráti unikátne elementy.First()- Vráti prvý element.Last()- Vráti posledný element.Intersect(collection)- Vráti prienik zoznamu so zadanou kolekciou.Union(collection)- Vráti zjednotenie `zoznamu so zadanou kolekciou.Min()- Vráti najmenší prvok.Max()- Vráti najväčší prvok.Sum()- Vráti súčet prvkov.Take(count)- Vráti prvky od začiatku kolekcieList.
Vidíme, že kolekcia List toho dokáže oveľa viac než pole.
Najväčšou výhodou je pridávanie a mazanie prvkov. Daň vo výkone je
zanedbateľná. V kurze s kolekciami zistíme, že List má ešte
ďalšie metódy, ale zatiaľ na to nemáme skúsenosti.
Program na ukladanie žrebovaných čísel bol zaujímavý, ale určite sa nám bude v budúcnosti hodiť ukladať skôr objekty než čísla.
V nasledujúcom cvičení, Riešené úlohy k 14.-15. lekcii OOP v C# .NET, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 7x (55.96 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

David sa informačné technológie naučil na