Skip to Content
Course content

32: Collections: List, Dictionary, HashSet

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I was reviewing code for a junior dev who was building a simple inventory system for a warehouse app. He had used a standard array to store the product IDs. It worked fine during the demo with five items, but as soon as we hit the staging environment with thousands of products, the app crawled to a halt. Why? Because every time he wanted to check if an item existed, he was running a for loop through the entire array. He was essentially asking the computer to read a whole book from page one every time he wanted to find a single word. It was a classic case of using the wrong tool for the job.

In C#, arrays are great when you know exactly how many elements you have and that number never changes. But in the real world, data is messy. It grows, it shrinks, and you often need to find things instantly without looping. That's where the System.Collections.Generic namespace comes in.

The Flexibility of Dynamic Lists

Most of the time, when you think "I need a list of things," you want a List<T>. Unlike an array, a List doesn't require a fixed size up front. It handles the resizing logic under the hood, so you can just keep calling .Add() until you run out of RAM.

var players = new List<string>();
players.Add("Alice");
players.Add("Bob");
players.Add("Charlie");

// Removing is just as easy
players.Remove("Bob"); 

Console.WriteLine($"We have {players.Count} players online.");

I usually tell people to treat List<T> as their default choice. If you don't have a specific reason to use something else, start here. Just keep in mind that searching for an item in a list still requires a linear scan (O(n) for the math nerds), so if your list grows to ten thousand items, .Contains() will start to slow you down.

Instant Lookups with Dictionaries

When you need to associate a piece of data with a unique identifier—like a User ID mapped to a User object—you want a Dictionary<TKey, TValue>. This is a "hash map," and it's incredibly fast. Instead of looping through every entry, the dictionary uses a hash of the key to jump directly to the value.

var inventory = new Dictionary<string, int>
{
    { "Apple", 50 },
    { "Banana", 100 },
    { "Orange", 20 }
};

// The "pro" way to get a value without risking a KeyNotFoundException
if (inventory.TryGetValue("Apple", out int count))
{
    Console.WriteLine($"We have {count} apples.");
}

One thing to watch out for: keys must be unique. If you try to .Add() a key that already exists, C# will throw an exception. If you're not sure if the key exists, use TryGetValue as shown above, or use the indexer (inventory["Apple"] = 60) which will either update the existing value or create a new one.

Filtering Duplicates with HashSets

Sometimes you don't need a value associated with a key; you just need to know if something exists in a group, and you want to make sure nothing is in there twice. That's exactly what a HashSet<T> is for. It's essentially a List that forbids duplicates and provides the same lightning-fast lookup speed as a Dictionary.

var uniqueVisitorIds = new HashSet<int>();

uniqueVisitorIds.Add(101);
uniqueVisitorIds.Add(102);
uniqueVisitorIds.Add(101); // This will be ignored; it's already there.

Console.WriteLine(uniqueVisitorIds.Count); // Output: 2

I use HashSet all the time when I'm processing logs or API responses where the source might send me the same record multiple times. Instead of writing a complex loop to check if an item is already present before adding it, I just dump everything into a HashSet and let the collection handle the deduplication for me.




📋 Practical Task

Exercise: Building a Unique Guest List and RSVP Tracker

You are tasked with creating a simple guest management system for an event. The system needs to handle two specific requirements: ensuring no guest is added twice and keeping track of each guest's meal preference.

Requirements:

  • Create a HashSet<string> to store the names of guests who have confirmed their attendance.
  • Create a Dictionary<string, string> where the key is the guest's name and the value is their meal choice (e.g., "Vegan", "Beef", "Fish").
  • Write a method ProcessRSVP(string name, string meal) that:
    1. Attempts to add the guest name to the HashSet.
    2. If the guest was successfully added (meaning they weren't already on the list), add their name and meal preference to the Dictionary.
    3. If the guest was already present, print a message saying "Guest [name] is already registered."
  • Test your system by adding "Alice" with "Vegan", "Bob" with "Beef", and then trying to add "Alice" again with "Fish".
  • Finally, print the total number of unique guests and the meal preference for "Bob".
Rating
0 0

There are no comments for now.

to be the first to leave a comment.