Verwendung von HashSet in C #

Ein HashSet ist eine optimierte Sammlung ungeordneter, eindeutiger Elemente, die schnelle Suchvorgänge und leistungsstarke Set-Operationen ermöglicht. Die HashSet-Klasse wurde erstmals in .NET 3.5 eingeführt und ist Teil des System.Collection.Generic-Namespace. Dieser Artikel beschreibt, wie wir mit HashSets in C # arbeiten können.

Um mit den in diesem Artikel bereitgestellten Codebeispielen arbeiten zu können, muss Visual Studio 2019 auf Ihrem System installiert sein. Wenn Sie noch keine Kopie haben, können Sie Visual Studio 2019 hier herunterladen.

Erstellen Sie ein .NET Core-Konsolenanwendungsprojekt in Visual Studio

Zunächst erstellen wir ein .NET Core Console-Anwendungsprojekt in Visual Studio. Angenommen, Visual Studio 2019 ist auf Ihrem System installiert, führen Sie die folgenden Schritte aus, um ein neues .NET Core Console-Anwendungsprojekt in Visual Studio zu erstellen.

  1. Starten Sie die Visual Studio-IDE.
  2. Klicken Sie auf "Neues Projekt erstellen".
  3. Wählen Sie im Fenster "Neues Projekt erstellen" aus der Liste der angezeigten Vorlagen "Konsolen-App (.NET Core)" aus.
  4. Weiter klicken.
  5. Geben Sie im nächsten Fenster "Konfigurieren Sie Ihr neues Projekt" den Namen und den Speicherort für das neue Projekt an.
  6. Klicken Sie auf Erstellen.

Dadurch wird ein neues .NET Core-Konsolenanwendungsprojekt in Visual Studio 2019 erstellt. In den folgenden Abschnitten dieses Artikels wird dieses Projekt für die Arbeit mit HashSet verwendet.

Was ist ein HashSet?

Ein HashSet - dargestellt durch die HashSet-Klasse, die sich auf den System.Collections.Generic-Namespace bezieht - ist eine leistungsstarke, ungeordnete Sammlung eindeutiger Elemente. Daher ist ein HashSet nicht sortiert und enthält keine doppelten Elemente. Ein HashSet unterstützt auch keine Indizes - Sie können nur Enumeratoren verwenden. Ein HashSet wird normalerweise für Hochleistungsvorgänge verwendet, bei denen eine Reihe eindeutiger Daten verwendet wird.

Die HashSet-Klasse implementiert mehrere Schnittstellen, wie unten gezeigt:

öffentliche Klasse HashSet: System.Collections.Generic.ICollection,

System.Collections.Generic.IEnumerable,

System.Collections.Generic.IReadOnlyCollection,

System.Collections.Generic.ISet,

System.Runtime.Serialization.IDeserializationCallback,

System.Runtime.Serialization.ISerializable

Da HashSet nur eindeutige Elemente enthält, ist seine interne Struktur für schnellere Suchvorgänge optimiert. Beachten Sie, dass Sie einen einzelnen Nullwert in einem HashSet speichern können. Daher ist HashSet eine gute Wahl, wenn Sie eine Sammlung wünschen, die eindeutige Elemente enthält und die Elemente in der Sammlung schnell durchsucht werden können.

Suchen Sie ein Element in einem HashSet in C #

Um ein Element in einem HashSet zu suchen, können Sie die Contains-Methode verwenden, wie im folgenden Code-Snippet gezeigt:

statische Leere Main (string [] args)

        {

            HashSet hashSet = new HashSet ();

            hashSet.Add ("A");

            hashSet.Add ("B");

            hashSet.Add ("C");

            hashSet.Add ("D");

            if (hashSet.Contains ("D"))

                Console.WriteLine ("Das erforderliche Element ist verfügbar.");

            sonst

                Console.WriteLine ("Das erforderliche Element ist nicht verfügbar.");

            Console.ReadKey ();

        }}

HashSet-Elemente sind immer eindeutig

Wenn Sie versuchen, ein doppeltes Element in ein HashSet einzufügen, wird es einfach ignoriert, es wird jedoch keine Laufzeitausnahme ausgelöst. Das folgende Codefragment veranschaulicht dies.

statische Leere Main (string [] args)

{

   HashSet hashSet = new HashSet ();

   hashSet.Add ("A");

   hashSet.Add ("B");

   hashSet.Add ("C");

   hashSet.Add ("D");

   hashSet.Add ("D");

   Console.WriteLine ("Die Anzahl der Elemente ist: {0}", hashSet.Count);

   Console.ReadKey ();

}}

Wenn Sie das Programm ausführen, erfolgt die Ausgabe wie in Abbildung 1 dargestellt.

Betrachten Sie nun das folgende Codefragment, das veranschaulicht, wie doppelte Elemente entfernt werden:

Zeichenfolge [] Städte = neue Zeichenfolge [] {

                "Delhi",

                "Kolkata",

                "New York",

                "London",

                "Tokio",

                "Washington",

                "Tokio"

            };

            HashSet hashSet = neues HashSet (Städte);

            foreach (var city in hashSet)

            {

                Console.WriteLine (Stadt);

            }}

Wenn Sie das obige Programm ausführen, werden die doppelten Städtenamen entfernt.

Entfernen Sie Elemente aus einem HashSet in C #

Um ein Element aus einem HashSet zu entfernen, sollten Sie die Remove-Methode aufrufen. Die Syntax der Remove-Methode ist unten angegeben.

public bool Remove (T-Element);

Wenn das Element in der Auflistung gefunden wird, entfernt die Remove-Methode ein Element aus dem HashSet und gibt bei Erfolg true zurück, andernfalls false.

Das unten angegebene Code-Snippet zeigt, wie Sie mit der Remove-Methode ein Element aus einem HashSet entfernen können.

string item = "D";

if (hashSet.Contains (item))

{

   hashSet.Remove (item);

}}

Um alle Elemente aus einem HashSet zu entfernen, können Sie die Clear-Methode verwenden.

Verwenden Sie HashSet-Set-Operations-Methoden in C #

HashSet verfügt über eine Reihe wichtiger Methoden für Set-Operationen wie IntersectWith, UnionWith, IsProperSubsetOf, ExceptWith und SymmetricExceptWith.

IsProperSubsetOf

Die IsProperSubsetOf-Methode wird verwendet, um zu bestimmen, ob eine HashSet-Instanz eine geeignete Teilmenge einer Sammlung ist. Dies ist in dem unten angegebenen Code-Snippet dargestellt.

HashSet setA = new HashSet () {"A", "B", "C", "D"};

HashSet setB = new HashSet () {"A", "B", "C", "X"};

HashSet setC = new HashSet () {"A", "B", "C", "D", "E"};

if (setA.IsProperSubsetOf (setC))

   Console.WriteLine ("setC enthält alle Elemente von setA.");

if (! setA.IsProperSubsetOf (setB))

   Console.WriteLine ("setB enthält nicht alle Elemente von setA.");

Wenn Sie das obige Programm ausführen, sollte die folgende Ausgabe im Konsolenfenster angezeigt werden.

UnionWith

Die UnionWith-Methode wird zum Hinzufügen von Sätzen verwendet, wie im folgenden Code-Snippet dargestellt.

HashSet setA = new HashSet () {"A", "B", "C", "D", "E"};

HashSet setB = new HashSet () {"A", "B", "C", "X", "Y"};

setA.UnionWith (setB);

foreach (string str in setA)

{

   Console.WriteLine (str);

}}

Wenn Sie den obigen Code ausführen, werden die Elemente von setB in setA kopiert. SetA enthält nun also "A", "B", "C", "D", "E", "X" und "Y". 

IntersectWith 

Die IntersectWith-Methode wird verwendet, um den Schnittpunkt zweier HashSets darzustellen. Hier ist ein Beispiel, um dies zu verstehen.

HashSet setA = new HashSet () {"A", "B", "C", "D", "E"};

HashSet setB = new HashSet () {"A", "X", "C", "Y"};

setA.IntersectWith (setB);

foreach (string str in setA)

{

    Console.WriteLine (str);

}}

Wenn Sie das obige Programm ausführen, werden im Konsolenfenster nur die Elemente angezeigt, die den beiden HashSets gemeinsam sind. Die Ausgabe würde folgendermaßen aussehen: 

Außer mit

Die ExceptWith-Methode repräsentiert die mathematische Mengen-Subtraktion und ist eine O (n) -Operation. Angenommen, Sie haben zwei HashSets setA und setB und geben die folgende Anweisung an:

setA.ExceptWith (setB);

Dies würde die Elemente von setA zurückgeben, die in setB nicht vorhanden sind. Lassen Sie uns dies anhand eines anderen Beispiels verstehen. Betrachten Sie das unten angegebene Code-Snippet.

HashSet setA = new HashSet () {"A", "B", "C", "D", "E"};

HashSet setB = new HashSet () {"A", "X", "C", "Y"};

setA.ExceptWith (setB);

foreach (string str in setA)

{

   Console.WriteLine (str);

}}

Wenn Sie das obige Programm ausführen, werden die Elemente "B", "D" und "E" im Konsolenfenster gedruckt (siehe Abbildung 5).

SymmetricExceptWith 

Die SymmetricExceptWith-Methode wird verwendet, um ein HashSet so zu ändern, dass es nur die eindeutigen Elemente von zwei HashSets enthält, dh die Elemente, die nicht beiden HashSets gemeinsam sind. Betrachten Sie das folgende Codefragment, das dies veranschaulicht.

HashSet setA = new HashSet () {"A", "B", "C", "D", "E"};

HashSet setB = new HashSet () {"A", "X", "C", "Y"};

setA.SymmetricExceptWith (setB);

foreach (string str in setA)

{

  Console.WriteLine (str);

}}

Wenn Sie den obigen Code ausführen, werden im Konsolenfenster nur die eindeutigen Elemente von setA und setB angezeigt, dh die Elemente, die in setA, aber nicht in setB vorhanden sind, und die Elemente, die in setB, aber nicht in setA vorhanden sind wie in Abbildung 6 gezeigt.

Während die durchschnittliche Komplexität für den Zugriff auf ein Element in einem Array O (n) beträgt, wobei n die Anzahl der Elemente im Array darstellt, beträgt die Komplexität nur O (1) für den Zugriff auf ein bestimmtes Element in einem HashSet. Dies macht HashSet zu einer guten Wahl für schnelle Suchvorgänge und zum Ausführen von Set-Operationen. Sie können eine Liste verwenden, wenn Sie eine Sammlung von Elementen in einer bestimmten Reihenfolge speichern und möglicherweise auch Duplikate einschließen möchten. 

So machen Sie mehr in C #:

  • Verwendung benannter und optionaler Parameter in C #
  • Benchmarking von C # -Code mit BenchmarkDotNet
  • Verwendung fließender Schnittstellen und Methodenverkettung in C #
  • So testen Sie statische Methoden in C #
  • Wie man Gottobjekte in C # umgestaltet
  • Verwendung von ValueTask in C #
  • Verwendung der Unveränderlichkeit in C.
  • Verwendung von const, readonly und static in C #
  • Verwendung von Datenanmerkungen in C #
  • So arbeiten Sie mit GUIDs in C # 8
  • Wann wird eine abstrakte Klasse im Vergleich zur Schnittstelle in C # verwendet?
  • So arbeiten Sie mit AutoMapper in C #
  • Verwendung von Lambda-Ausdrücken in C #
  • So arbeiten Sie mit Action-, Func- und Predicate-Delegaten in C #
  • So arbeiten Sie mit Delegierten in C #
  • So implementieren Sie einen einfachen Logger in C #
  • So arbeiten Sie mit Attributen in C #
  • So arbeiten Sie mit log4net in C #
  • So implementieren Sie das Repository-Entwurfsmuster in C #
  • Wie man mit Reflexion in C # arbeitet
  • So arbeiten Sie mit dem Dateisystemwatcher in C #
  • So führen Sie eine verzögerte Initialisierung in C # durch
  • So arbeiten Sie mit MSMQ in C #
  • So arbeiten Sie mit Erweiterungsmethoden in C #
  • Wie wir Lambda-Ausdrücke in C #
  • Wann wird das flüchtige Schlüsselwort in C # verwendet?
  • Verwendung des Schlüsselwortsield in C #
  • So implementieren Sie Polymorphismus in C #
  • So erstellen Sie Ihren eigenen Taskplaner in C #
  • So arbeiten Sie mit RabbitMQ in C #
  • So arbeiten Sie mit einem Tupel in C #
  • Erkundung virtueller und abstrakter Methoden in C #
  • Verwendung des Dapper ORM in C #
  • Verwendung des Entwurfsmusters im Fliegengewicht in C #