EMZETT.
Login

Kurz: Ein Array hat eine feste Größe und gleichartige Elemente:

Teil des Kurses C#

Kapitel 6 von 16 im Kurs C# (Abschnitt „Daten und Objekte“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Arrays

Ein Array hat eine feste Größe und gleichartige Elemente:

int[] zahlen = { 5, 3, 9, 1, 7 };
string[] namen = new string[3];
namen[0] = "Mia";
Console.WriteLine($"{zahlen[0]} {zahlen.Length} {namen[1] ?? "leer"} {zahlen[^1]}");
 
Array.Sort(zahlen);
Console.WriteLine(string.Join(" ", zahlen));
Array.Reverse(zahlen);
Console.WriteLine(string.Join(" ", zahlen) + " | " + Array.IndexOf(zahlen, 9));
 
int[,] matrix = { { 1, 2, 3 }, { 4, 5, 6 } };               // zweidimensional
Console.WriteLine($"{matrix[1, 2]} {matrix.GetLength(0)} {matrix.GetLength(1)}");
int[][] gezackt = { new[] { 1 }, new[] { 2, 3 } };           // Array von Arrays
Console.WriteLine(gezackt[1][1]);
 
try { Console.WriteLine(zahlen[10]); }
catch (IndexOutOfRangeException e) { Console.WriteLine("Fehler: " + e.Message); }

Ausgabe:

5 5 leer 7
1 3 5 7 9
9 7 5 3 1 | 0
6 2 3
3
Fehler: Index was outside the bounds of the array.

List<T>: die wachsende Liste

List<T> ist die Standardwahl, wenn du viele Elemente verwaltest:

var namen = new List<string> { "Mia", "Tom" };
namen.Add("Zoe");
namen.Insert(1, "Ben");
namen.AddRange(new[] { "Eva", "Jan" });
Console.WriteLine($"{namen.Count} {namen[0]} {namen.Contains("Tom")} {namen.IndexOf("Zoe")}");
namen.Remove("Tom");
namen.RemoveAt(0);
namen.Sort();
Console.WriteLine(string.Join(", ", namen));
namen.RemoveAll(n => n.StartsWith("E"));
Console.WriteLine(string.Join(", ", namen) + " | " + namen.Find(n => n.Length == 3));
 
var zahlen = new List<int> { 5, 3, 9, 1 };
zahlen.Sort((a, b) => b.CompareTo(a));                       // absteigend
Console.WriteLine(string.Join(" ", zahlen) + " | max " + zahlen.Max() + " | Summe " + zahlen.Sum());
List<int> kopie = new(zahlen);                               // Kurzform von new List<int>(...)
kopie.Add(100);
Console.WriteLine($"{zahlen.Count} {kopie.Count}");

Ausgabe:

6 Mia True 3
Ben, Eva, Jan, Zoe
Ben, Jan, Zoe | Ben
9 5 3 1 | max 9 | Summe 18
4 5

Dictionary<K, V>: Schlüssel und Werte

var alter = new Dictionary<string, int> { ["Mia"] = 17, ["Tom"] = 19 };
alter["Zoe"] = 21;
alter["Mia"] = 18;                                           // überschreibt
alter.TryAdd("Tom", 99);                                      // nur wenn neu
Console.WriteLine($"{alter["Mia"]} {alter.ContainsKey("Max")} {alter.Count}");
 
if (alter.TryGetValue("Zoe", out int z)) Console.WriteLine($"Zoe ist {z}");
Console.WriteLine(alter.GetValueOrDefault("Max", -1));
 
foreach (var (name, jahre) in alter.OrderBy(p => p.Key)) Console.Write($"{name}={jahre} ");
Console.WriteLine();
Console.WriteLine(string.Join(",", alter.Keys.OrderBy(k => k)) + " " + alter.Values.Sum());
 
try { Console.WriteLine(alter["Unbekannt"]); }
catch (KeyNotFoundException) { Console.WriteLine("Schlüssel fehlt"); }
 
// Wörter zählen
var haeufigkeit = new Dictionary<string, int>();
foreach (var wort in "das ist das beste und das letzte".Split(' '))
    haeufigkeit[wort] = haeufigkeit.GetValueOrDefault(wort) + 1;
Console.WriteLine(string.Join(", ", haeufigkeit.OrderByDescending(p => p.Value).ThenBy(p => p.Key).Take(2).Select(p => $"{p.Key}:{p.Value}")));

Ausgabe:

18 False 3
Zoe ist 21
-1
Mia=18 Tom=19 Zoe=21
Mia,Tom,Zoe 58
Schlüssel fehlt
das:3, beste:1

Der Zugriff dict["x"] wirft einen Fehler bei fehlendem Schlüssel. Nimm TryGetValue oder GetValueOrDefault.

Weitere Collections

TypZweck
HashSet<T>Menge ohne Duplikate, schnelles Contains
SortedSet<T>, SortedDictionary<K,V>sortiert
Queue<T>Warteschlange (FIFO): Enqueue, Dequeue
Stack<T>Stapel (LIFO): Push, Pop
LinkedList<T>doppelt verkettet
PriorityQueue<T, P>nach Priorität
ImmutableList<T> etc.unveränderlich (System.Collections.Immutable)
ConcurrentDictionary<K,V>threadsicher
var menge = new HashSet<int> { 1, 2, 3, 3, 2 };
menge.UnionWith(new[] { 3, 4 });
Console.WriteLine($"{menge.Count} {menge.Contains(4)} " + string.Join(",", menge.OrderBy(x => x)));
var a = new HashSet<int> { 1, 2, 3, 4 };
a.IntersectWith(new[] { 3, 4, 5 });
Console.WriteLine(string.Join(",", a));
 
var schlange = new Queue<string>();
schlange.Enqueue("A"); schlange.Enqueue("B"); schlange.Enqueue("C");
Console.WriteLine($"{schlange.Dequeue()} {schlange.Peek()} {schlange.Count}");
 
var stapel = new Stack<int>();
stapel.Push(1); stapel.Push(2); stapel.Push(3);
Console.WriteLine($"{stapel.Pop()} {stapel.Peek()}");
 
var pq = new PriorityQueue<string, int>();
pq.Enqueue("niedrig", 5); pq.Enqueue("hoch", 1); pq.Enqueue("mittel", 3);
Console.WriteLine(pq.Dequeue() + " " + pq.Dequeue());

Ausgabe:

4 True 1,2,3,4
3,4
A B 2
3 2
hoch mittel

Sammlungs-Ausdrücke (C# 12)

int[] z = [1, 2, 3];
List<string> l = ["a", "b"];
int[] alle = [.. z, 4, 5];                                    // Spread
Console.WriteLine($"{z.Length} {l.Count} {string.Join(",", alle)}");

Ausgabe:

3 2 1,2,3,4,5

Welche Sammlung?

AufgabeWahl
feste Größe, schnellArray
wachsende ListeList<T>
Suchen nach SchlüsselDictionary<K, V>
Duplikate vermeiden / prüfenHashSet<T>
Reihenfolge FIFO / LIFOQueue<T> / Stack<T>

Gib aus Methoden gern IEnumerable<T> oder IReadOnlyList<T> zurück, damit der Aufrufer die interne Liste nicht ändern kann.

Merke

  • Arrays haben feste Größe; List<T> wächst; Dictionary<K, V> ordnet Schlüssel Werten zu
  • TryGetValue und GetValueOrDefault statt Zugriff, der einen Fehler werfen kann
  • HashSet, Queue, Stack, PriorityQueue decken Mengen und Warteschlangen ab
  • Sammlungs-Ausdrücke [1, 2, 3] und Spread .. (C# 12)
  • Nach außen IEnumerable<T>/IReadOnlyList<T> anbieten

Übungsaufgabe

Zähle Buchstaben in einem Text mit einem Dictionary<char, int> und gib die drei häufigsten aus.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Methoden

Weiter: Klassen, Eigenschaften und Konstruktoren

Alle Kapitel: C# im Überblick