0Pricing
C# Academy · Lekcja

Lista w praktyce

Doda, usunie i wyszuka Pan/Pani elementy.

Lista w praktyce to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 1 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.

Dlaczego List<T>?

List<T> to używana na co dzień dynamiczna tablica w języku C#. Znajduje się w System.Collections.Generic i automatycznie powiększa się podczas dodawania elementów.

W przeciwieństwie do zwykłej tablicy nie trzeba z góry ustalać jej rozmiaru. Jest bezpieczna typowo: List<int> przechowuje wyłącznie wartości int, a niezgodność jest wykrywana podczas kompilacji.

using System.Collections.Generic;

List<int> scores = new List<int>();
scores.Add(90);
scores.Add(85);

Tworzenie i inicjalizacja

Listę można od razu wypełnić za pomocą inicjalizatora kolekcji. Taki zapis jest zwięzły i czytelny.

Kompilator zamienia każdą pozycję w wywołanie Add w tle, więc wynik jest identyczny jak przy dodawaniu elementów pojedynczo.

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var fruits = new List<string> { "apple", "pear", "plum" };
        Console.WriteLine(fruits.Count);
    }
}

Indeksowanie i Count

Do elementów uzyskuje się dostęp za pomocą indeksu numerowanego od zera, tak jak w tablicy. list[0] to pierwszy element.

Aby sprawdzić, ile elementów zawiera lista, należy użyć Count, a nie Length. Odczyt lub zapis za pomocą indeksu zajmuje stały czas O(1).

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var nums = new List<int> { 10, 20, 30 };
        Console.WriteLine(nums[1]);
        Console.WriteLine(nums.Count);
    }
}

Dodawanie i wstawianie

Add dodaje element na końcu w zamortyzowanym czasie O(1). AddRange dodaje wiele elementów jednocześnie.

Insert(index, item) umieszcza element na wskazanej pozycji, przesuwając wszystkie znajdujące się za nim elementy. To przesunięcie sprawia, że wstawianie na początku za pomocą Insert ma koszt O(n), dlatego gdy jest to możliwe, lepiej dodawać elementy na końcu.

var list = new List<string> { "b", "c" };
list.Insert(0, "a");
list.AddRange(new[] { "d", "e" });
// list is now a, b, c, d, e

Usuwanie elementów

Remove(item) usuwa pierwszą pasującą wartość i zwraca true, jeśli ją znaleziono. RemoveAt(index) usuwa element według pozycji.

Obie metody przesuwają późniejsze elementy w lewo, dlatego usuwanie ze środka ma koszt O(n). RemoveAll przyjmuje predykat i usuwa wszystkie pasujące elementy w jednym przebiegu.

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var nums = new List<int> { 1, 2, 3, 4, 5 };
        nums.RemoveAll(n => n % 2 == 0);
        Console.WriteLine(string.Join(",", nums));
    }
}

Wyszukiwanie na liście

Contains informuje, czy dana wartość istnieje, a IndexOf zwraca jej pozycję lub -1. Obie metody przeszukują listę liniowo, w czasie O(n).

Jeśli często wyszukuje Pan/Pani wartości na dużej liście, ten liniowy koszt szybko się sumuje. Lepszym wyborem może być HashSet lub Dictionary.

var names = new List<string> { "Ann", "Bob", "Cy" };
bool hasBob = names.Contains("Bob");   // true
int pos = names.IndexOf("Cy");          // 2

Iterowanie

Pętla foreach to najbardziej przejrzysty sposób odczytania każdego elementu. Można też użyć klasycznej pętli for, gdy potrzebny jest indeks.

Nie należy dodawać ani usuwać elementów wewnątrz pętli foreach przechodzącej po tej samej liście, ponieważ spowoduje to wyjątek InvalidOperationException.

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var colors = new List<string> { "red", "green", "blue" };
        foreach (var c in colors)
            Console.WriteLine(c);
    }
}

Sortowanie

Sort() sortuje listę w miejscu za pomocą domyślnego komparatora. Aby użyć niestandardowej kolejności, należy przekazać delegat porównania.

Sortowanie ma koszt O(n log n). Aby uzyskać posortowaną kopię bez zmieniania oryginału, można użyć OrderBy z LINQ, które zwraca nową sekwencję.

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var nums = new List<int> { 4, 1, 3, 2 };
        nums.Sort();
        Console.WriteLine(string.Join(",", nums));
    }
}

Capacity a Count

Count oznacza liczbę istniejących elementów, a Capacity — liczbę elementów, które lista może przechować przed ponownym przydzieleniem wewnętrznej tablicy.

Gdy lista przekroczy pojemność, przydzielana jest większa tablica, a elementy są do niej kopiowane, zwykle przy podwojeniu rozmiaru. Jeśli znany jest końcowy rozmiar listy, należy przekazać go do konstruktora, aby uniknąć wielokrotnego kopiowania.

var list = new List<int>(1000); // reserve capacity
for (int i = 0; i < 1000; i++)
    list.Add(i);
// no intermediate reallocations

Lista jako argument metody

List<T> jest typem referencyjnym. Przekazanie jej do metody oznacza przekazanie referencji, dlatego zmiany wprowadzone wewnątrz metody wpływają na listę wywołującego.

Jeśli metoda tylko odczytuje dane, należy przyjąć IEnumerable<T> lub IReadOnlyList<T>, aby zasygnalizować, że lista nie będzie modyfikowana.

using System;
using System.Collections.Generic;

class Program {
    static void AddOne(List<int> xs) => xs.Add(1);
    static void Main() {
        var nums = new List<int>();
        AddOne(nums);
        Console.WriteLine(nums.Count); // 1
    }
}

Konwertowanie i kopiowanie

ToArray() tworzy tablicę o stałym rozmiarze, a new List<T>(other) tworzy płytką kopię innej sekwencji.

Płytka kopia powiela strukturę listy, ale współdzieli referencje do tych samych elementów, dlatego modyfikacja obiektu zawartego na liście jest widoczna przez obie listy.

var original = new List<int> { 1, 2, 3 };
int[] arr = original.ToArray();
var copy = new List<int>(original);

Szybkie sprawdzenie

Wybierz operację, której koszt wyraźnie się wyróżnia.

Podsumowanie

List<T> to rozszerzalna tablica bezpieczna typowo. Dostęp za pomocą indeksu i Count mają koszt O(1), a Add na końcu działa w zamortyzowanym czasie O(1).

Wstawianie, usuwanie i wyszukiwanie wartości w środku listy mają koszt O(n) z powodu przesuwania lub przeszukiwania. Gdy rozmiar jest znany, warto zarezerwować pojemność, aby uniknąć ponownego przydzielania pamięci.

Często zadawane pytania

Czy lekcja „Lista w praktyce” jest bezpłatna?

Tak — pełny tekst „Lista w praktyce” 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 „Lista w praktyce”?

Doda, usunie i wyszuka Pan/Pani elementy. Ć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 1 z 4.

Ile czasu zajmuje lekcja „Lista w praktyce”?

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