Где я могу узнать о различных типах списков .NET?

Кто-нибудь знает хороший ресурс, чтобы кратко объяснить различные типы списков, доступных на С#, и когда их использование подходит?

Например, List, Hashtable, Словари и т.д.

Я никогда не уверен, когда я буду использовать что.

Ответ 1

Это не все списки, хотя они все коллекции. Вот краткое резюме.

Не общие коллекции (API находится в терминах object. Типы значений помещаются в коробки.

Это в основном System.Collections пространство имен:

  • ArrayList: список элементов, поддерживаемых массивом. Быстрый случайный доступ для чтения/записи. Быстрое добавление к концу, если буфер не требует изменения размера.
  • Hashtable: Карта от ключа к значению. Ключи уникальны, значения не обязательно. Использует метод GetHashCode для достижения доступа O/1 к чтению/записи (кроме неприятных случаев, когда все элементы имеют один и тот же хеш, или резервное хранилище нуждается в перестройке). Итерация по парам ключ/значение дает непредсказуемый порядок. (Ну, эффективно непредсказуем.)
  • SortedList: Как Hashtable, но записи всегда возвращаются в порядке сортировки по ключу. Сохраняется как список пар ключ/значение.
  • Stack: коллекция Last-in-first-out
  • Queue: коллекция First-in-first-out
  • Array: случайный доступ с фиксированным размером O (1); не общий, но также имеет строго типизированные формы

Общие коллекции. (Сильно типизированный API, не будет вводить типы значений (предполагая подходящий T).

Это в основном System.Collections.Generic пространство имен:

Возможно, наиболее важным интерфейсом для коллекции является IEnumerableIEnumerable &lt, T > ). Это представляет собой последовательность элементов, очень похожую на поток, представляет собой последовательность байтов. Нет никакого произвольного доступа, просто чтение вперед. LINQ to Objects основывается на этом, и почти все его типы реализуют.

Ответ 2

Вы должны забрать книгу об основных структурах данных. Это та же самая теория, независимо от языка.

Краткое объяснение:

  • Array: (как, например, int[] myArray) - статический массив, который может использоваться, когда коллекция никогда не изменяется (вы не можете добавлять или удалять элементы в ней, но вы можете изменять значения отдельных элементов)
  • ArrayList: массив/список общего назначения, который позволяет относительно быстрое перечисление, а также прямой доступ. Этот список может автоматически увеличиваться при добавлении элементов, но поскольку он хранит только Object, вам редко приходится использовать его из-за проблем с производительностью и типом безопасности.
  • List<T>: общая версия вышеупомянутого массива ArrayList. Он обеспечивает хороший баланс между производительностью и гибкостью и должен использоваться почти всегда, когда у вас есть динамический плоский список элементов. (Новый в .NET 2.0)
  • Hashtable: работает как плоский список, но вместо индексации его целыми числами он может быть проиндексирован с использованием любого объекта. Стоит отметить, что в хэш-таблице нет "порядка".
  • Dictionary<T>: общая версия Hashtable. Используйте это в .NET 2.0 и выше вместо Hashtable по тем же причинам, что и для ArrayList vs List выше.
  • Stack<T>: Предоставляет первый список в списке. Элемент, который вы добавили последним, будет элементом, который вы получите первым, когда вы выберете что-то.
  • Queue<T>: Предоставляет первый список в первом списке. Подумайте об этом как о трубке, где вы вставляете предметы на одном конце и выбираете их на другом конце. Обычно используется для передачи сообщений между, например, потоки.

В общем, вы должны использовать общие коллекции практически для всего, что вы делаете в .NET 2.0 и выше. Вы получите полную безопасность по типу (по сравнению с, например, ArrayList и HashTable), и они намного быстрее для типов значений (целые числа, структуры, поплавки и т.д.) По сравнению с непиковыми.

Если у вас есть список элементов, которые никогда не будут меняться, или вам не нужна/нужна гибкость List<T>, вы можете, конечно, использовать массив, так как он имеет наименьшее количество накладных расходов.

Рекомендация при возврате коллекции из общедоступного метода или свойства заключается в том, чтобы отдать ее на менее гибкий интерфейс. Поэтому, если у вас есть список, который вы вернете, вы можете применить его к IEnumerable<int>, что означает, что ваш потребитель не может добавлять к нему элементы (если, конечно, он не отбрасывает его, но все равно указывает на пользователей). Кроме того, это позволит вам гибко изменить базовую структуру данных, сохраняя при этом стабильность API. Вы также можете выбрать ICollection<int> или IList<int>, чтобы показать немного больше функциональности, но не скрывать фактическую структуру данных.

Ответ 3

Чтобы изложить предыдущий ответ tobsen, C6 Generic Collection Library имеет большое количество коллекций. Я опишу некоторые из них здесь:

Очередь /Stack

  • CircularQueue<T>: этот класс обеспечивает строго функциональность Queue и Stack. Кроме того, эффективный доступ O (1) к любому элементу в Stack/Queue доступен с помощью индексатора: cq[0] (где 0 является самым старым элементом, рядом с которым будет выведено из очереди, последним будет выталкиваться).

Списки

Примечание: ArrayList и LinkedList также могут работать как Queue/Stacks

  • ArrayList<T>. Подобно его аналогу в System.Collections.Generic (SCG), List<T>, это поддерживается массивом, гарантирующим O (1) индексирование, но наихудший вариант O (n).O(n), чтобы найти элемент.
  • LinkedList<T>: Как и его аналог SCG.LinkedList<T>. Используя двусвязный список, гарантирует O (1) вставку, но худшая индексация O (n) (на практике пропорциональна расстоянию от головы или хвоста списка). Также O (n), чтобы найти элемент. Сортировка использует стабильную сортировку Merge.
  • HashedArrayList<T>: аналогично ArrayList<T> выше, но не позволяет дублировать. Преимущество, которое вы получаете взамен, заключается в том, что время нахождения элемента и его индекса сводится к O (1).
  • HashedLinkedList<T>: аналогично LinkedList<T> выше, но не позволяет дублировать. Как и раньше, время нахождения элемента сводится к O (1), но время нахождения его индекса остается O (n).
  • WrappedArray<T>: он похож на ArrayList<T>, он действует как обертка вокруг массива, реализующего C5.IList<T>, но генерирует исключения, если делается попытка изменить коллекцию (IsFixedSize - true и Add, Remove, Insert не работают, Sort, Shuffle и Reverse делают, однако, поскольку они являются операциями на месте).

Списки также предоставляют функциональность "Вид", которая представляет сегмент базового списка, позволяя выполнять локальные операции. Используя шаблоны, предлагаемые в книге C5, операции могут выполняться с использованием представлений, которые эффективны как для массива, так и для связанных списков. Любая операция списка также может выполняться в представлении, ограничивая их действие подмножеством базового списка.

Сортированные коллекции

  • SortedArray<T>: аналогично ArrayList<T>, за исключением того, что он сохраняет свои элементы отсортированными и не позволяет дублировать. Обратите внимание, что случайные вставки и удаления в этой коллекции медленны. Эта коллекция лучше всего, если количество элементов мало или редко изменено, но часто доступно по индексу или значению элемента.
  • TreeSet<T>: Использует красно-черную структуру дерева для сортировки предметов. Как набор, он не позволяет дублировать. Доступ по индексу или значению элемента, а также вставка/удаление принимают O (log n).
  • TreeBag<T>: Использует красно-черное дерево, сохраняя отсортированные предметы. Как мешок, он позволяет дублировать, но не хранит дубликаты в дереве, а сохраняет дубликаты путем подсчета.

Оба TreeSet<T> и TreeBag<T> предоставляют возможность эффективно создавать "моментальные снимки" или постоянные копии дерева в O (1), позволяя итерацию по снимку при изменении базового дерева. Обратите внимание, что каждый снимок на дереве добавляет штраф за производительность к обновлениям для дерева, но эти эффекты исчезают при размещении моментального снимка.

Коллекции хэшей

  • HashSet<T>: коллекция, использующая простую хеш-таблицу для хранения. Доступ по позиции item принимает значение O (1). Как набор, он не позволяет дублировать. Предоставляет функцию BucketCostDistribution(), которая может помочь вам определить эффективность функции хэш-кода элементов.
  • HashBag<T>: Подобно HashSet<T>, но имеет семантику пакета, что означает, что дубликаты разрешены, но дубликаты сохраняются только путем подсчета.

Приоритетная очередь

  • IntervalHeap<T>: Обеспечивает приоритетную очередь. Поиск максимального и минимального числа операций O (1), удаление максимума, минимума, добавление и обновление - это операции O (log n). Позволяет дублировать, сохраняя их явно (не путем подсчета).

Словари

  • HashDictionary<H,K>: Подобно SCG.Dictionary<H,K>, предоставляет доступ к вводу, вставку и удаление в O (1). Также предоставляет функцию BucketCostDistribution() как HashSet<T> выше. Не гарантирует какой-либо конкретный порядок перечисления.
  • TreeDictionary<H,K>. Подобно SCG.SortedDictionary<H,K>, он содержит постоянно отсортированный словарь с использованием красно-черного дерева. Вход, вставка и удаление входа выполняются O (log n). Гарантирует, что перечисление словаря следует порядку, указанному ключевым компаратором.

Защищенные коллекции

Кроме того, C5 также предлагает "охраняемые" коллекции, которые эффективно действуют как обертка только для чтения, что предотвращает изменение коллекции. Элементы в коллекции все еще могут быть изменены, но элементы не могут быть добавлены, удалены или вставлены в коллекцию.

Длинный ответ, но тщательно изучите библиотеки C5 в разных коллекциях. Я нашел библиотеку C5 отличной и часто использую ее в своем собственном коде, заменив общий заголовок С# на:

using C5;
using SCG = System.Collections.Generic;

Ответ 4

Карты хэшей

  • Словарь
  • Hashtable (не общий)

Это структура данных, которая позволяет сохранять пары ключ-значение. Учитывая ключ, который имеет некоторый способ заказа, вы можете вставить значение. Простым примером может быть список студентов, в которых ключ является идентификатором студента, а также значением имени студента.

Списки произвольного доступа

  • Список
  • ArrayList (не общий)

Списки случайного доступа используются для хранения длинного списка объектов, к которым необходимо получить доступ случайным образом (т.е. вы хотите получить доступ к n-му элементу в O (1) раз). Нехорошо, если вы хотите вставлять/удалять элементы в середине списка, поскольку для этого потребуется перетасовать весь список, который может занять некоторое время.

Связанные списки и аналогичные

  • LinkedList
  • Queue
  • Stack

Связанные списки великолепны, если вы не хотите получать доступ к элементам посередине, так как это займет время O (N). Это здорово, если вы хотите вставлять/удалять элементы в середине, поскольку это связано только с изменением нескольких указателей.

Очереди и стеки немного специализированы, поскольку они оптимизированы для поведения FIFO и FILO (First-In-First-Out и First-In-First-Out соответственно).

Ответ 5

Если вы начинаете с MSDN doco для System.Collections, вы можете развернуть отдельные типы коллекций для получения более подробной информации об этих "списки" и способы их использования. Например, doco для Hashtable говорит: "Представляет коллекцию пар ключ/значение, которые организованы на основе хеш-кода ключа".

Там также приятное обсуждение System.Collections.Generic в Общие сведения.

Ответ 6

Список < Т > сортируется, но не рекомендуется публично публиковать.

Коллекция < Т > представляет собой базовую, без излишеств коллекцию.

Словарь < Т > представляет собой набор пар ключ-значение (как и старая хэш-таблица, но теперь общая).

KeyedCollection < Т > это словарь, в котором ключ может быть определен из значения (это абстрактный, поэтому вы должны наследовать его и поддерживать функцию GetKey)

ReadOnlyCollection < Т > является специальной коллекцией, в которой содержимое не может быть изменено.

ArrayList и HashTable в основном устарели, начиная с .NET 2.0.

Ответ 7

В дополнение к большим ответам до сих пор есть еще несколько Коллекций, доступных через C5 Generic Collection Library. Документация (также на их сайте) может помочь при принятии решения о том, что использовать в зависимости от ваших требований.

Ответ 8

В MSDN есть статья под названием Выбор класса коллекции, который мне очень пригодится, когда вы пытаетесь выяснить, какую коллекцию использовать в данной ситуации.

Ответ 9

Это примеры различных типов общих структур данных. Эти структуры данных используются повсюду в разработке программного обеспечения.

Ответ 10

Intellisense покажет вам краткое описание каждого, если вы просто наберете System.collections.Generic. в окне кода. Не забывайте о завершающем периоде. О, и там также System.Collections.ObjectModel.. Оттуда вы сможете получить больше информации о том, что выглядит перспективным с MSDN.