0Pricing
C# Academy · Lekcja

Wybór kolekcji

Kompromisy i wydajność.

Wybór kolekcji to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.

Najpierw jedno pytanie

Wybór kolekcji należy rozpocząć od jednego pytania: jak będą uzyskiwać Państwo dostęp do danych? Według pozycji, według klucza czy tylko przez sprawdzanie przynależności?

List, Dictionary i HashSet odpowiadają różnym sposobom dostępu. Dopasowanie narzędzia do sposobu użycia sprawia, że kod pozostaje szybki i czytelny.

Dostęp według pozycji: List

Jeśli kolejność ma znaczenie, a dostęp do elementów odbywa się za pomocą indeksu, należy wybrać List<T>. Zachowuje kolejność wstawiania i zapewnia indeksowanie o złożoności O(1).

Przykłady to kolejka kroków, wiersze w kolejności wyświetlania lub dowolna sekwencja, po której iterują Państwo od początku do końca. Duplikaty są dozwolone.

var steps = new List<string> { "mix", "bake", "cool" };
string first = steps[0]; // O(1) by index

Dostęp według klucza: Dictionary

Jeśli wyszukują Państwo elementy według unikatowego identyfikatora, należy wybrać Dictionary<K,V>. Mapuje on klucz na wartość ze średnią złożonością O(1).

Przykłady to identyfikator użytkownika mapowany na użytkownika, kod kraju mapowany na nazwę lub słowo mapowane na jego licznik. Klucz odpowiada na pytanie „który element?”, a wartość zawiera dane.

var users = new Dictionary<int, string> {
    [101] = "Ann",
    [102] = "Bob"
};
string name = users[101];

Przynależność i unikatowość: HashSet

Jeśli istotne jest tylko to, czy dana wartość występuje, albo trzeba odrzucać duplikaty, należy wybrać HashSet<T>. Contains ma średnią złożoność O(1).

Przykłady to odwiedzone adresy URL, dozwolone uprawnienia i różne tagi. Nie ma tu powiązanej wartości — liczy się sama obecność elementu.

var visited = new HashSet<string>();
if (visited.Add(url)) {
    // first time seeing this url
}

Tabela kosztów

Średnie koszty: indeksowanie List ma złożoność O(1), ale Contains — O(n). Wyszukiwanie w Dictionary i HashSet ma złożoność O(1).

List.Add na końcu ma zamortyzowaną złożoność O(1), natomiast wstawianie lub usuwanie w środku ma złożoność O(n). Dodawanie i usuwanie w Dictionary oraz HashSet ma średnią złożoność O(1).

// List:       index O(1),  Contains O(n)
// Dictionary: by-key O(1), no index
// HashSet:    Contains O(1), no value, no index

List.Contains to sygnał ostrzegawczy

Wielokrotne wywoływanie list.Contains wewnątrz pętli prowadzi do pułapki o złożoności O(n kwadrat). Każde sprawdzenie przeszukuje całą listę.

Jeśli sprawdzanie przynależności dominuje w kodzie, należy przełączyć się na HashSet. Ta pojedyncza zmiana może przekształcić powolną pętlę w błyskawiczną operację na dużych zbiorach danych.

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var allow = new HashSet<int> { 2, 4, 6 };
        foreach (int n in new[] { 1, 2, 3, 4 })
            if (allow.Contains(n)) Console.Write(n + " ");
    }
}

Gdy potrzebne są zarówno klucz, jak i kolejność

Potrzebują Państwo wyszukiwania według klucza, ale także przewidywalnej kolejności? Standardowy Dictionary nie gwarantuje kolejności.

Można przechowywać List do obsługi kolejności obok Dictionary do wyszukiwania albo użyć SortedDictionary<K,V>, który utrzymuje klucze w kolejności sortowania kosztem O(log n).

var sorted = new SortedDictionary<string, int>();
sorted["b"] = 2;
sorted["a"] = 1;
// enumerates a then b, in key order

Kompromisy dotyczące pamięci

Kolekcje oparte na haszowaniu wymieniają większe zużycie pamięci na szybkość. Dictionary i HashSet przechowują wewnętrzne kubełki, zużywając więcej pamięci niż zwarta List lub tablica.

W przypadku małych kolekcji zawierających zaledwie kilka elementów skanowanie List może być zupełnie wystarczające i zużywać mniej pamięci. Haszowanie przynosi korzyści przy większej skali.

Programowanie względem interfejsów

Sygnatury metod powinny wymagać typu możliwie najmniej szczegółowego, który spełnia dane wymagania. Do odczytu należy przyjmować IEnumerable<T>, do odczytu indeksowanego — IReadOnlyList<T>, a do dostępu według klucza — IDictionary<K,V>.

Oddziela to kod wywołujący od konkretnego wyboru implementacji, umożliwiając późniejszą zamianę implementacji bez łamania sygnatur.

int Sum(IEnumerable<int> values) {
    int total = 0;
    foreach (int v in values) total += v;
    return total;
}

Przykład praktyczny

Zliczanie unikatowych słów w tekście wykorzystuje dwie kolekcje jednocześnie. HashSet śledzi napotkane słowa, a Dictionary zlicza ich wystąpienia.

Każda kolekcja dobrze realizuje swoje zadanie: zbiór zapewnia unikatowość, a słownik mapuje słowo na częstotliwość — w obu przypadkach średnia złożoność operacji wynosi O(1).

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var counts = new Dictionary<string, int>();
        foreach (var w in "a b a c b a".Split(' '))
            counts[w] = counts.GetValueOrDefault(w) + 1;
        Console.WriteLine(counts["a"]); // 3
    }
}

Lista kontrolna wyboru

Należy odpowiedzieć kolejno na pytania: Czy potrzebna jest mapa klucza na wartość? Należy użyć Dictionary. Czy potrzebna jest tylko unikatowość lub sprawdzanie przynależności? Należy użyć HashSet.

Jeśli nie, czy potrzebne są kolejność i dostęp przez indeks, ewentualnie z duplikatami? Należy użyć List. Ta krótka lista obejmuje większość codziennych przypadków.

Szybkie sprawdzenie

Należy zastosować listę kontrolną wyboru do konkretnej potrzeby.

Podsumowanie

Wybór zależy od sposobu dostępu: List służy do uporządkowanych sekwencji z dostępem przez indeks, Dictionary do wyszukiwania wartości według klucza, a HashSet do zapewniania unikatowości i sprawdzania przynależności.

Należy zwracać uwagę na notację Big-O: unikać List.Contains w często wykonywanych pętlach, korzystać z haszowanych wyszukiwań O(1) i programować względem interfejsów, aby zachować elastyczność wyboru.

Często zadawane pytania

Czy lekcja „Wybór kolekcji” jest bezpłatna?

Tak — pełny tekst „Wybór kolekcji” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wybór kolekcji”?

Kompromisy i wydajność. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C# Academy?

Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Wybór kolekcji”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?

Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Lista w praktyce
  2. Wyszukiwanie w Dictionary
  3. HashSet i unikatowość
  4. Wybór kolekcji
← Powrót do C# Academy