# HashSet

A HashSet&lt;T> holds each value once, answers "is it in here?" fast, and has no index or guaranteed order. Add tells you whether a value was new.

Journeyman · C# · Updated November 3, 2026

## After this lesson you can

- Use a HashSet&lt;T> to keep values without duplicates, with Add, Contains and Remove
- Choose between a List&lt;T> and a HashSet&lt;T> for a job

## Key takeaways

- A `HashSet<T>` holds each value once. `Add` returns `true` when the value is new and `false` when it's already there.
- `Contains` tells you fast whether a value is in the set, however big the set grows.
- A set has no index and no guaranteed order. Loop over it with `foreach`, and never depend on the order values come out.
- `IntersectWith` keeps only the values both sets have, and `UnionWith` adds everything from the other set.
- Use a `List<T>` when order, positions or duplicates matter, and a `HashSet<T>` when each value should appear once.

A **`HashSet<T>`** is a collection that holds each value **only once**. It's the collection to reach for when the question is *"have I seen this before?"*

## No duplicates

```csharp
HashSet<string> visitors = new HashSet<string>();

Console.WriteLine(visitors.Add("Ada"));
Console.WriteLine(visitors.Add("Grace"));
Console.WriteLine(visitors.Add("Ada"));

Console.WriteLine($"{visitors.Count} different visitors");
Console.WriteLine(visitors.Contains("Grace"));
Console.WriteLine(visitors.Contains("Linus"));
```

```text
True
True
False
2 different visitors
True
False
```

`Add` returns `true` when the value is new, and `false` when it's already there; adding it again changes nothing. `Contains` answers whether a value is in the set, and it answers fast, however big the set grows.

| Member | Does |
|---|---|
| `Add(value)` | Adds the value if it's new; returns whether it was added |
| `Contains(value)` | Whether the value is in the set |
| `Remove(value)` | Removes the value; returns whether it was there |
| `Count` | How many values the set holds |

## No index, no order

A set has no positions: there's no `visitors[0]`. To see every value, loop over it with `foreach`. And don't count on the order: a `HashSet` keeps values in whatever order suits it, not the order you added them, and not sorted.

```csharp
HashSet<int> seatsSold = new HashSet<int> { 14, 3, 9 };
seatsSold.Add(3);
seatsSold.Remove(9);

Console.WriteLine($"{seatsSold.Count} seats sold");
foreach (int seat in seatsSold)
{
    Console.WriteLine($"Seat {seat} is taken");
}
```

```text
2 seats sold
Seat 14 is taken
Seat 3 is taken
```

(The loop happened to print 14 before 3. Code that depends on a set's order is a bug waiting to happen.)

## Two sets together

Sets can be combined. `IntersectWith` keeps only what both sets have, and `UnionWith` adds everything from the other set:

```csharp
HashSet<string> adaKnows = new HashSet<string> { "C#", "SQL", "HTML" };
HashSet<string> jobNeeds = new HashSet<string> { "C#", "SQL", "Angular" };

HashSet<string> matches = new HashSet<string>(adaKnows);
matches.IntersectWith(jobNeeds);
Console.WriteLine($"Matching skills: {matches.Count}");
Console.WriteLine(matches.Contains("Angular"));
```

```text
Matching skills: 2
False
```

`new HashSet<string>(adaKnows)` makes a copy first, so `adaKnows` itself isn't changed.

## List or HashSet?

| Use a `List<T>` when | Use a `HashSet<T>` when |
|---|---|
| The order matters | Only "is it in there?" matters |
| Duplicates are allowed, or meaningful | Each value should appear once |
| You need items by position: `list[0]` | You check `Contains` often, on many values |
| Example: the items on an order, in order | Example: the seats already sold, the tags on a post |

## Check yourself

2 questions to try on the lesson page.

## So what

When duplicates would be a bug, a `HashSet` makes them impossible, and it answers "is this one taken?" instantly. Seats, tags, usernames, visited pages: anything that should appear once belongs in a set.

## Key terms

- [HashSet&lt;T>](https://www.ask-codey.com/glossary/hashset-t)

## Cheat sheets

- [HashSet](https://www.ask-codey.com/cheat-sheets/advanced-collections-in-csharp-hashset-cheat-sheet)

Source: https://www.ask-codey.com/lessons/advanced-collections-in-csharp-hashset
