HashSet und Eindeutigkeit
Verwalten Sie unterschiedliche Werte.
HashSet und Eindeutigkeit ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Was ist ein HashSet?
HashSet<T> speichert eine Sammlung eindeutiger Werte ohne Duplikate. Das Hinzufügen eines bereits vorhandenen Werts hat einfach keine Wirkung.
Wie ein Dictionary basiert es auf einer Hashtabelle, sodass Prüfungen, ob ein Element enthalten ist, durchschnittlich O(1) benötigen. Die Einfügereihenfolge bleibt nicht erhalten.
using System.Collections.Generic;
var seen = new HashSet<int>();
seen.Add(1);
seen.Add(1); // ignored, still one elementAdd gibt einen booleschen Wert zurück
Add gibt true zurück, wenn der Wert neu war, und false, wenn er bereits vorhanden war.
Dieser Rückgabewert ist nützlich, um Duplikate in einem Schritt zu erkennen, ohne eine separate Prüfung mit Contains durchzuführen.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var set = new HashSet<string>();
Console.WriteLine(set.Add("a")); // True
Console.WriteLine(set.Add("a")); // False
}
}Schnelle Mitgliedschaftsprüfungen
Contains für ein HashSet benötigt durchschnittlich O(1), verglichen mit O(n) für eine List.
Wenn Sie wiederholt fragen: „Habe ich dieses Element bereits gesehen?“, ist ein Set das richtige Werkzeug. Je größer die Sammlung wird, desto deutlicher fällt der Geschwindigkeitsunterschied aus.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var ids = new HashSet<int> { 10, 20, 30 };
Console.WriteLine(ids.Contains(20)); // True
Console.WriteLine(ids.Contains(99)); // False
}
}Duplikate aus einer List entfernen
Eine häufige Aufgabe: Nehmen Sie eine Liste und behalten Sie nur eindeutige Werte. Das Erstellen eines HashSet aus der Liste erledigt dies in O(n).
Das resultierende Set enthält jeden Wert genau einmal. Wenn Sie wieder eine Liste benötigen, erstellen Sie daraus eine: new List<int>(set).
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var nums = new List<int> { 1, 2, 2, 3, 3, 3 };
var unique = new HashSet<int>(nums);
Console.WriteLine(unique.Count); // 3
}
}Vereinigung
UnionWith fügt jedes Element einer anderen Sammlung hinzu und überspringt Duplikate. Das Ergebnis enthält alle Elemente aus beiden Sammlungen.
Dadurch wird das Set direkt verändert. Das ist deutlich übersichtlicher, als selbst eine Schleife zu schreiben und für jedes Element Add aufzurufen.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var a = new HashSet<int> { 1, 2, 3 };
a.UnionWith(new[] { 3, 4, 5 });
Console.WriteLine(a.Count); // 5
}
}Schnittmenge
IntersectWith behält nur die Elemente, die auch in der anderen Sammlung vorkommen, und entfernt den Rest.
Verwenden Sie es, um gemeinsame Elemente zu finden, etwa Tags, die zwei Artikeln gemeinsam sind, oder Benutzer, die in beiden Gruppen vorkommen.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var a = new HashSet<int> { 1, 2, 3, 4 };
a.IntersectWith(new[] { 2, 4, 6 });
Console.WriteLine(string.Join(",", a)); // 2,4
}
}Differenz
ExceptWith entfernt aus dem Set jedes Element, das in der anderen Sammlung vorkommt. Übrig bleibt, was nur im Set enthalten ist.
Es handelt sich um die Mengenoperation A ohne B: „Elemente in A, aber nicht in B“. Das ist ideal, um zu berechnen, was sich geändert hat oder noch verarbeitet werden muss.
var a = new HashSet<int> { 1, 2, 3, 4 };
a.ExceptWith(new[] { 2, 4 });
// a now contains 1 and 3Teilmenge und Obermenge
IsSubsetOf und IsSupersetOf prüfen die Enthaltenseinsbeziehungen zwischen Mengen und geben einen bool zurück.
Overlaps prüft, ob mindestens ein Element in beiden Mengen vorkommt, und SetEquals prüft, ob zwei Mengen unabhängig von der Reihenfolge genau dieselben Elemente enthalten.
var a = new HashSet<int> { 1, 2 };
var b = new HashSet<int> { 1, 2, 3 };
bool sub = a.IsSubsetOf(b); // true
bool ov = a.Overlaps(b); // trueElementgleichheit
Die Eindeutigkeit hängt von GetHashCode und Equals des Elementtyps ab, genau wie bei Dictionary-Schlüsseln.
Bei benutzerdefinierten Typen überschreiben Sie beide Methoden oder verwenden Sie ein record. Andernfalls werden zwei logisch gleiche Objekte als verschieden behandelt und landen beide im Set.
var names = new HashSet<string>(
System.StringComparer.OrdinalIgnoreCase);
names.Add("Sam");
bool dup = !names.Add("SAM"); // true: treated as sameKein Indexzugriff und keine garantierte Reihenfolge
Ein HashSet bietet keinen Indexzugriff; Sie können nicht set[0] schreiben. Sie können es nur mit foreach durchlaufen.
Die Reihenfolge der Enumeration ist nicht garantiert. Wenn Sie sowohl Eindeutigkeit als auch eine sortierte Reihenfolge benötigen, verwenden Sie SortedSet<T>. Es hält die Elemente sortiert, allerdings mit Operationen der Komplexität O(log n).
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var s = new SortedSet<int> { 3, 1, 2 };
Console.WriteLine(string.Join(",", s)); // 1,2,3
}
}Bereits gesehene Elemente verfolgen
Ein häufiges Muster besteht darin, einen Datenstrom so zu filtern, dass jeder Wert nur einmal vorkommt. Fügen Sie jeden Wert einem Set hinzu und verarbeiten Sie ihn nur, wenn Add true zurückgibt.
Das ist übersichtlicher und schneller, als eine wachsende Liste zu prüfen, und macht aus einer Suche mit O(n²) eine mit O(n).
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var seen = new HashSet<int>();
foreach (int x in new[] { 1, 1, 2, 3, 2 })
if (seen.Add(x)) Console.Write(x + " ");
// prints 1 2 3
}
}Kurzer Test
Rufen Sie sich in Erinnerung, was ein HashSet garantiert und wie hoch die Kosten für das Nachschlagen sind.
Zusammenfassung
HashSet<T> speichert eindeutige Werte. Hinzufügen, Entfernen und Prüfungen auf Zugehörigkeit benötigen durchschnittlich O(1), jedoch gibt es weder eine Reihenfolge noch einen Indexzugriff.
Es eignet sich besonders zum Entfernen von Duplikaten, für schnelle Prüfungen nach dem Muster „Habe ich dieses Element bereits gesehen?“ und für Mengenoperationen mit UnionWith, IntersectWith und ExceptWith. Bei benutzerdefinierten Elementtypen ist eine korrekte Gleichheit erforderlich.
Häufig gestellte Fragen
Ist die Lektion „HashSet und Eindeutigkeit“ kostenlos?
Ja — der vollständige Text von „HashSet und Eindeutigkeit“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „HashSet und Eindeutigkeit“?
Verwalten Sie unterschiedliche Werte. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C# Academy zu starten?
Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „HashSet und Eindeutigkeit“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?
Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Listen in der Praxis
- Dictionary-Suchen
- HashSet und Eindeutigkeit
- Eine Collection auswählen