HashSet, Queue and Stack
Three specialised collections: unique items with fast lookups, first-in-first-out processing, and last-in-first-out undo history.
HashSet<T>: unique items
var used = new HashSet<string> { "IPE200", "HEA200" };Console.WriteLine(used.Add("IPE200")); // False: already thereConsole.WriteLine(used.Add("IPE300")); // TrueConsole.WriteLine(used.Contains("HEA200"));Console.WriteLine(used.Count); // remove duplicates from any list in one linevar unique = new HashSet<int>(new[] { 3, 1, 3, 2, 1 });Console.WriteLine(string.Join(" ", unique));False True True 3 3 1 2
a.UnionWith(b) (everything in either), a.IntersectWith(b) (only in both), a.ExceptWith(b) (in a but not b). Great for “which profiles are in model A but not in model B?”.
Queue<T>: first in, first out
var jobs = new Queue<string>();jobs.Enqueue("Export IFC");jobs.Enqueue("Generate drawings");jobs.Enqueue("Send report"); while (jobs.Count > 0){ string job = jobs.Dequeue(); // oldest first Console.WriteLine($"Running: {job}");}Running: Export IFC Running: Generate drawings Running: Send report
Stack<T>: last in, first out
var undo = new Stack<string>();undo.Push("Draw beam B1");undo.Push("Add bolt group");undo.Push("Move column C3"); Console.WriteLine($"Undo: {undo.Pop()}"); // most recent firstConsole.WriteLine($"Undo: {undo.Pop()}");Console.WriteLine($"Next to undo: {undo.Peek()}");Undo: Move column C3 Undo: Add bolt group Next to undo: Draw beam B1
Safe versions
if (undo.TryPop(out string? action)) Console.WriteLine(action);if (jobs.TryDequeue(out string? next)) Console.WriteLine(next);Pop, Peek and Dequeue throw InvalidOperationException when the collection is empty; the Try versions return false instead.
Collection cheat sheet
| Collection | Order | Duplicates | Best at |
|---|---|---|---|
List<T> | |||
Dictionary<K,V> | |||
HashSet<T> | |||
Queue<T> | |||
Stack<T> | |||
SortedDictionary<K,V> |
"(a[b]{c})" is balanced and "(a[b)]" is not.
Show a hint
Show the solution
static bool Balanced(string s){ var stack = new Stack<char>(); foreach (char c in s) { if (c is '(' or '[' or '{') stack.Push(c); else if (c is ')' or ']' or '}') { if (stack.Count == 0) return false; char open = stack.Pop(); if ((c == ')' && open != '(') || (c == ']' && open != '[') || (c == '}' && open != '{')) return false; } } return stack.Count == 0;} Console.WriteLine(Balanced("(a[b]{c})"));Console.WriteLine(Balanced("(a[b)]"));True False
Remember
HashSet<T>: unique items, O(1)Contains, set operations.Queue<T>: FIFO withEnqueue/Dequeue.Stack<T>: LIFO withPush/Pop/Peek.Use TryPop/TryDequeueto avoid exceptions on empty collections.