← Все вопросы

Чем HashSet лучше List когда нужны только уникальные значения?

Задан 13 месяцев назад707 просмотров2 ответа
9

Учу C# и наткнулся на HashSet<T>. Не очень понимаю, зачем он нужен, если есть List<T>. У меня задача — собрать список ID пользователей без повторов. Сейчас делаю так:

var ids = new List<int>();
foreach (var id in input)
{
    if (!ids.Contains(id))
        ids.Add(id);
}

Выглядит костыльно. Есть способ лучше? И вообще, чем HashSet отличается от List?

2 ответа

16
✓ Принятый ответ — помог автору

HashSet<T> — это коллекция уникальных элементов. Она сама не даёт добавить дубликат, поэтому ваш цикл с проверкой Contains не нужен:

var ids = new HashSet<int>();
foreach (var id in input)
    ids.Add(id); // дубликаты просто игнорируются

// или ещё короче:
var unique = new HashSet<int>(input);

Главное отличие от List — это скорость поиска. List.Contains перебирает все элементы по очереди — это O(n). HashSet.Contains использует хеши и работает за O(1) в среднем. На больших данных разница огромная.

Ключевые различия:

List<T> HashSet<T>
Дубликаты разрешены запрещены
Порядок сохраняется не гарантируется
Поиск Contains O(n) O(1)
Доступ по индексу есть list[i] нет

Берите List, когда важен порядок и индексы. Берите HashSet, когда нужна уникальность и быстрая проверка «есть ли элемент».

Бонус — у HashSet есть операции множеств:

var a = new HashSet<int> { 1, 2, 3 };
var b = new HashSet<int> { 2, 3, 4 };
a.IntersectWith(b); // a теперь { 2, 3 }
6

Если коротко: HashSet нужен именно для уникальности и быстрых проверок «содержится / не содержится».

Один нюанс новичкам: HashSet не хранит порядок добавления. Если вам важно, чтобы элементы шли в том же порядке, в каком пришли, но при этом без дублей — тогда либо List + проверка, либо Distinct() из LINQ:

using System.Linq;
var unique = input.Distinct().ToList(); // порядок сохраняется

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект