Lekcja 8. Tablice i kolekcje (List, Dictionary)
ŚredniPo co się tego uczymy?
Prawdziwe programy niemal zawsze operują na WIELU danych naraz — liście filmów, klientów, produktów w koszyku. Bez tablic i kolekcji musiałbyś tworzyć osobną zmienną dla każdego elementu, co jest niepraktyczne już przy kilku elementach, a niemożliwe przy setkach.
Teoria
Dotąd każda zmienna przechowywała JEDNĄ wartość. Tablice i kolekcje pozwalają przechowywać WIELE wartości pod jedną nazwą.
Tablica — zbiór elementów tego samego typu, o STAŁYM, ustalonym z góry rozmiarze:
string[] imiona = { "Ala", "Bartek", "Celina" };
Dostęp do elementu przez indeks, liczony OD ZERA: imiona[0] to "Ala", imiona[2] to "Celina". Rozmiar tablicy sprawdzisz przez imiona.Length.
Tablice dwuwymiarowe — "tabela" danych (wiersze i kolumny):
int[,] plansza = new int[3, 3]; — dostęp przez plansza[wiersz, kolumna].
List<T> — dynamiczna lista, której rozmiar może się ZMIENIAĆ w trakcie działania programu (dodawanie/usuwanie elementów):
List<string> koszyk = new List<string>();
koszyk.Add("Mleko"); dodaje element, koszyk.Remove("Mleko") usuwa, koszyk.Count zwraca aktualną liczbę elementów.
Dictionary<TKey, TValue> — zbiór par klucz-wartość (jak słownik: szukasz po kluczu, dostajesz wartość):
Dictionary<string, int> wiekOsob = new Dictionary<string, int>();
wiekOsob["Ala"] = 18; zapisuje, wiekOsob["Ala"] odczytuje wartość przypisaną do klucza "Ala".
Krotki (Tuples) — pozwalają zwrócić lub przechowywać KILKA wartości różnych typów razem, bez tworzenia osobnej klasy: (string, int) osoba = ("Ala", 18);
Schemat
Tablica (rozmiar STAŁY, ustalony przy tworzeniu):
[ 0 ] [ 1 ] [ 2 ] [ 3 ]
"Ala" "Bartek" "Celina" "Darek"
List<T> (rozmiar ZMIENNY - można dodawać/usuwać):
["Ala", "Bartek"] --Add("Celina")--> ["Ala", "Bartek", "Celina"]
Dictionary<TKey, TValue> (klucz -> wartość):
"Ala" -> 18
"Bartek" -> 20
Przykład z życia
Koszyk zakupowy w każdym sklepie internetowym to w praktyce List<T> — kolekcja, do której produkty są dodawane i z której są usuwane w dowolnym momencie, w przeciwieństwie do tablicy o stałym rozmiarze.
Kod (C#)
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// tablica - stały rozmiar
string[] filmy = { "Podróż w czasie", "Ostatni bastion", "Cichy ocean" };
Console.WriteLine("Liczba filmów: " + filmy.Length);
Console.WriteLine("Pierwszy film: " + filmy[]);
// List<T> - zmienny rozmiar
List<string> koszyk = new List<string>();
koszyk.Add("Podróż w czasie");
koszyk.Add("Ostatni bastion");
Console.WriteLine("Filmów w koszyku: " + koszyk.Count);
foreach (string tytul in koszyk)
{
Console.WriteLine("W koszyku: " + tytul);
}
// Dictionary<TKey, TValue> - ceny filmów po tytule
Dictionary<string, double> ceny = new Dictionary<string, double>();
ceny["Podróż w czasie"] = 9.99;
ceny["Ostatni bastion"] = 7.99;
Console.WriteLine("Cena: " + ceny["Podróż w czasie"] + " zł");
}
}
Komentarz i wyjaśnienie kodu
using System.Collections.Generic; jest konieczne, żeby korzystać z List<T> i Dictionary<TKey, TValue> — to osobna biblioteka od podstawowego System. Nazwa List<string> oznacza "lista przechowująca elementy typu string" — ten sam mechanizm (tzw. generyki) poznasz szerzej w Lekcji 17, tworząc WŁASNE klasy generyczne.
Ćwiczenie samodzielne
Utwórz tablicę z pięcioma swoimi ulubionymi filmami i wypisz je pętlą foreach (Lekcja 6).
Plac zabaw — wypróbuj online
Poniższy kod wykonuje się od razu w Twojej przeglądarce — nic nie trzeba instalować. Zmień kod i kliknij „Uruchom”.
Zadania do pracy własnej
Utwórz
List<int>z pięcioma liczbami, dodaj do niej jedną nową liczbę i wypisz sumę wszystkich elementów.Utwórz
Dictionary<string, int>przechowujący liczbę sztuk trzech produktów w magazynie, wypisz stan magazynu, a następnie zmniejsz liczbę sztuk jednego z produktów po "sprzedaży".Zbuduj prosty system oceniania:
Dictionary<string, List<int>>przechowujący listę ocen dla każdego ucznia (klucz: imię, wartość: lista ocen), dodaj kilka ocen kilku uczniom, a następnie wypisz średnią ocen dla każdego z nich.
Typowe błędy
Bardzo częsty błąd to próba odczytu elementu tablicy spoza jej zakresu (np. imiona[3] przy tablicy 3-elementowej, gdzie ostatni prawidłowy indeks to 2) — program zgłosi wyjątek IndexOutOfRangeException (o wyjątkach szerzej w Lekcji 16). Drugi błąd: próba dodania elementu do zwykłej tablicy metodą Add() — tablice mają STAŁY rozmiar, Add() istnieje tylko dla List<T>. Trzeci: odczyt z Dictionary nieistniejącego klucza — zgłosi wyjątek, warto najpierw sprawdzić ContainsKey().
Nawiązanie do egzaminu zawodowego
To realizacja efektu INF.04.3.2 z podstawy programowej: "posługuje się złożonymi typami danych" — wprost wymienia tablice 1D/2D, tablice dynamiczne/asocjacyjne oraz kolekcje jako wymagany zakres wiedzy.