I'm delighted to welcome you to our C# Sets lesson! In C#, sets are represented by the HashSet<T>
collection, which can only hold unique elements. They're particularly useful when you need to ensure that elements in a collection appear only once.
In this lesson, you'll consolidate your knowledge of creating and operating on sets using HashSet<T>
. You will learn about the advantages of using sets and how they enhance performance. Let's get started!
Let's begin by creating a set in C#. This can be done using the HashSet<T>
class.
C#1using System; 2using System.Collections.Generic; 3 4public class Program 5{ 6 public static void Main() 7 { 8 // Creating a HashSet and printing it 9 HashSet<int> mySet = new HashSet<int> { 1, 2, 3, 4, 5, 5, 5 }; // Duplicates will be omitted 10 Console.WriteLine(string.Join(", ", mySet)); // Output: 1, 2, 3, 4, 5 11 } 12}
C# provides methods to manipulate sets, such as Add
, Contains
, Remove
, and Clear
.
C#1using System; 2using System.Collections.Generic; 3 4public class Program 5{ 6 public static void Main() 7 { 8 HashSet<int> mySet = new HashSet<int> { 1, 2, 3, 4, 5 }; 9 10 // Adding an element 11 mySet.Add(6); // `mySet` is now { 1, 2, 3, 4, 5, 6 } 12 Console.WriteLine(mySet.Contains(1)); // Output: True, as `mySet` includes element 1 13 14 // Removing an element 15 mySet.Remove(1); // `mySet` becomes { 2, 3, 4, 5, 6 } 16 Console.WriteLine(mySet.Contains(1)); // Output: False, as `mySet` doesn't include 1 anymore 17 18 // Clearing the set 19 mySet.Clear(); // `mySet` becomes an empty set 20 Console.WriteLine(mySet.Count); // Output: 0 21 } 22}
Add
: Adds a specified element to the set.Contains
: Checks if the specified element exists in the set.Remove
: Removes a specified element from the set.Clear
: Removes all elements from the set.
C# provides built-in methods for operations such as union, intersection, and difference for sets through LINQ.
C#1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5public class Program 6{ 7 public static void Main() 8 { 9 HashSet<int> set1 = new HashSet<int> { 1, 2, 3, 4 }; // First set 10 HashSet<int> set2 = new HashSet<int> { 3, 4, 5, 6 }; // Second set 11 12 // Set union 13 var union = set1.Union(set2); 14 Console.WriteLine(string.Join(", ", union)); // Output: 1, 2, 3, 4, 5, 6 15 16 // Set intersection 17 var intersection = set1.Intersect(set2); 18 Console.WriteLine(string.Join(", ", intersection)); // Output: 3, 4 19 20 // Set difference 21 var difference = set1.Except(set2); 22 Console.WriteLine(string.Join(", ", difference)); // Output: 1, 2 23 } 24}
Union
: Combines elements from both sets, excluding any duplicates. In this case, the result is a set containing{1, 2, 3, 4, 5, 6}
.Intersect
: Returns a set with only the elements that are common to both sets. For these sets, the intersection is{3, 4}
.Except
: Returns a set containing elements that are in the first set but not in the second set. Here, the result is{1, 2}
forset1
.
One of the key advantages of sets is their faster performance in membership tests, thanks to their use of hashing.
C#1using System; 2using System.Collections.Generic; 3using System.Diagnostics; 4using System.Linq; 5 6public class Program 7{ 8 public static void Main() 9 { 10 Random random = new Random(); 11 HashSet<int> mySet = new HashSet<int>(Enumerable.Range(0, 10000000)); // A set of 10^7 elements 12 List<int> myList = Enumerable.Range(0, 10000000).ToList(); // A list with the same elements and order 13 14 // Warm-up 15 mySet.Contains(-1); 16 myList.Contains(-1); 17 18 // Measure HashSet performance 19 Stopwatch stopwatch = Stopwatch.StartNew(); 20 for (int i = 0; i < 1000; i++) 21 { 22 bool result = mySet.Contains(random.Next(10000000)); 23 } 24 stopwatch.Stop(); 25 Console.WriteLine("Set: " + stopwatch.ElapsedMilliseconds + "ms"); 26 27 // Measure List performance 28 stopwatch.Restart(); 29 for (int i = 0; i < 1000; i++) 30 { 31 bool result = myList.Contains(random.Next(10000000)); 32 } 33 stopwatch.Stop(); 34 Console.WriteLine("List: " + stopwatch.ElapsedMilliseconds + "ms"); 35 } 36}
- Membership Test with
HashSet<T>
: Thanks to hash tables, sets can check for membership in constant time, leading to quick lookup times. The time taken for checking membership in the set is remarkably low. - Membership Test with List: Lists require a linear search to check for membership, which results in longer lookup times as the list grows. The time taken for checking membership in the list is noticeably higher.
Congratulations! You've just explored creating and manipulating sets, performing set operations, and reaping the performance benefits of sets in C#.
Remember, practice is key to solidifying your understanding. Happy coding!