В чём разница между списком и словарём?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между списком и словарём в контексте C# и Unity
В C# и Unity разработке список (List<T>) и словарь (Dictionary<TKey, TValue>) — это две фундаментальные коллекции из пространства имён System.Collections.Generic, которые служат разным целям и имеют кардинально отличающиеся внутренние механизмы работы.
Ключевые различия
| Аспект | Список (List<T>) | Словарь (Dictionary<TKey, TValue>) |
|---|---|---|
| Основная цель | Упорядоченная коллекция элементов с доступом по индексу. | Неупорядоченная (до C# 7.3) коллекция пар "ключ-значение" для быстрого поиска по ключу. |
| Структура данных | Динамический массив. | Хеш-таблица. |
| Метод доступа | Целочисленный индекс (myList[0]). | Уникальный ключ любого типа (myDict["key"]). |
| Производительность (Big O) | Доступ по индексу: O(1). Поиск элемента: O(n). | Поиск, вставка, удаление по ключу: O(1) в среднем. |
| Порядок элементов | Гарантированно сохраняет порядок добавления. | Не гарантирует порядок (в современных версиях C# сохраняет порядок вставки, но полагаться на это не всегда стоит для логики). |
| Уникальность | Дубликаты элементов разрешены. | Ключи должны быть уникальными. Значения могут повторяться. |
Примеры использования в Unity
Список (List<T>)
Идеально подходит, когда важен порядок или вам нужен простой перебор всех элементов (например, список врагов на уровне, очередь задач, инвентарь, где порядок может иметь значение).
using System.Collections.Generic;
using UnityEngine;
public class EnemyManager : MonoBehaviour
{
public List<GameObject> enemies = new List<GameObject>();
void Start()
{
// Добавление
enemies.Add(Instantiate(enemyPrefab));
// Доступ по индексу
GameObject firstEnemy = enemies[0];
// Перебор
foreach (GameObject enemy in enemies)
{
enemy.GetComponent<Enemy>().TakeDamage(10);
}
}
}
Словарь (Dictionary<TKey, TValue>)
Незаменим для быстрого поиска данных по уникальному идентификатору (например, кэширование компонентов, хранение статов по их названию, система диалогов по ID реплики).
using System.Collections.Generic;
using UnityEngine;
public class ComponentCache : MonoBehaviour
{
private Dictionary<string, Renderer> _rendererCache = new Dictionary<string, Renderer>();
Renderer GetRendererByObjectName(string name)
{
// Быстрый поиск за O(1) вместо GetComponent или Find
if (!_rendererCache.TryGetValue(name, out Renderer renderer))
{
GameObject obj = GameObject.Find(name);
if (obj != null)
{
renderer = obj.GetComponent<Renderer>();
_rendererCache.Add(name, renderer); // Кэшируем
}
}
return renderer;
}
}
Критически важные моменты для собеседования
- Производительность: Главный аргумент. Используйте словарь, когда основной сценарий — частый поиск по уникальному ключу. Список для этого категорически не подходит, так как требует линейного перебора.
- Ключи и
GetHashCode: Ключи в словаре должны быть неизменяемыми (immutable) на протяжении его жизни. Для кастомных классов-ключей необходимо корректно переопределять методыGetHashCode()иEquals(), иначе словарь будет работать некорректно. - Выделение памяти:
Dictionaryв погоне за скоростью потребляет больше памяти, чемList, из-за структуры хеш-таблицы. - Итерация: Перебор всех элементов в
Listобычно чуть быстрее, чем вDictionary, так как в словаре итерация идет по внутренним "корзинам" (buckets) хеш-таблицы.
Вывод для Unity разработчика: Выбор между List и Dictionary — это классический компромисс между порядком/простотой и скоростью поиска. В игровой логике Dictionary часто используется для систем с быстрым доступом (базы данных предметов, конфигурация), а List — для динамически изменяющихся групп объектов, где важен порядок или индекс (юниты в отряде, карты в колоде игрока). Понимание этой разницы напрямую влияет на оптимизацию и архитектуру игрового кода.