System.Collections - почему так много вариантов? - PullRequest
2 голосов
/ 13 февраля 2009

Большая часть моего опыта программирования на языке, где есть одна структура данных коллекции - массив. Теперь, когда я работаю в основном в .NET, я оценил огромное количество доступных мне инструментов, но мне также трудно определить, какие инструменты лучше всего подходят для каждой проблемы. Я считаю, что это часто случается с коллекциями.

Я уверен, что смогу быстрее найти подходящий инструмент для работы с течением времени / опыта, но может ли кто-нибудь дать некоторые рекомендации относительно того, какие классы по сбору подходят для какой работы? Есть ли хорошие правила, которым нужно следовать?

РЕДАКТИРОВАТЬ: Я считаю, что я использую List (T) почти всегда, что является своего рода, что вызвало этот вопрос. Я знаю, что есть очень конкретные причины использовать другие классы. Хотя List (T) работает в большинстве случаев, я хочу избегать заклинивания чего-либо в общий список, когда лучше подходит другая структура. Я должен быть в состоянии определить эти случаи.

Спасибо!

Ответы [ 7 ]

15 голосов
/ 13 февраля 2009

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

C ++, например, изначально поддерживает только массивы «коллекций» (здесь «коллекции» используются очень свободно), но с добавлением указателей вы можете реализовать эквивалент для любой структуры данных коллекций, доступной в .Net. Фактически, если вы заглянете в стандартную библиотеку шаблонов C ++, вы найдете стандартные реализации для большинства общих структур.

Причиной дополнительных структур является то, что массив не всегда или даже часто является наиболее подходящей структурой для сбора данных. Он имеет ряд ограничений, которые могут быть решены одной или другой коллекцией, и, используя эти разные коллекции, вы часто можете получить намного большую производительность из намного меньше кода и уменьшить вероятность есть ошибка в реализации вашей структуры данных.

Решая, какой тип коллекции использовать, вам нужно посмотреть, как она будет использоваться Большинство из нас . Например, ожидается ли, что все объекты в коллекции принадлежат к одному типу, унаследованы от одного типа или какого-либо другого типа? Вы собираетесь часто добавлять и удалять предметы? Если да, будете ли вы всегда выдвигать / вставлять, ставить в очередь / удалять элементы или вам нужно добавлять элементы в определенные места? Будете ли вы искать конкретные элементы по ключу, индексу или обоим? Если по ключу, как определяется ключ?

Некоторые из наиболее распространенных коллекций:

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

  • LinkedList<T> должно звучать знакомо, если вы прошли какое-либо официальное обучение информатике. Он использует синтаксис, аналогичный списку, но оптимизируется по-другому: поиск выполняется медленнее, поскольку он требует обхода списка, а добавление или удаление элемента в определенную позицию может быть намного быстрее.

  • Dictionary<TKey, TValue> использует синтаксис, аналогичный List<T>, но вместо индекса массива вы вводите значение ключа в скобках. Словари хороши тем, что поиск определенных элементов по ключу считается очень быстрым , в том смысле, что независимо от того, сколько элементов в Словаре, всегда будет требоваться примерно одинаковое количество времени, чтобы найти тот, который вам нужен .

  • SortedList<TKey, TValue> работает во многом как словарь, за исключением того, что при его переборе возвращаются элементы, отсортированные по ключу. Тем не менее, вы не можете искать n-й элемент без предварительной итерации всех элементов перед ним.

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

  • Не забудьте старые резервные копии: Stack и Queue. Опять же, если у вас есть какое-либо формальное образование в области компьютерных наук, у вас уже должно быть довольно хорошее представление о том, как они работают, основываясь на их именах.

Наконец, большинство из этих коллекций (включая массив!) Реализуют набор общих интерфейсов. Эти интерфейсы очень полезны, так как вы можете написать программу для интерфейса, а не для определенной коллекции, и тогда ваша функция может принять любую коллекцию , которая реализует этот интерфейс. Например, следующий код будет работать независимо от того, передаете ли вы строковый массив, List<string> или любой другой IEnumerable<string>:

void WriteToConsole(IEnumerable<string> items)
{
    foreach (string item in items)
    {
       Console.WriteLine(item);
    }
}

Другие интерфейсы, на которые стоит обратить внимание: IList<T>, ICollection<T> и IQueryable<T>.

3 голосов
/ 13 февраля 2009

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

List<string> items = new List<string>();
items.Add("abc");
items.Add("dfg");

ArrayLists принимает любой объект как элемент. поэтому они хороши для хранения нескольких типизированных ситуаций. Например, если вам нужно хранить int и строку в одном и том же массиве коллекций, это хорошо.

ArrayList items = new ArrayList();
items.Add("abc");
items.Add(1);
items.Add(DateTime.Now);

SortedLists и Хеш-таблицы - это пары ключ-значение. Вы можете определить ключ для ваших предметов. это поможет вам быстро их найти. SortedLists автоматически сортирует Hastables.

Hashtable items1 = new Hashtable();
items1.Add("item1", "abc");
items1.Add("item2", "dfg");

SortedList items2 = new SortedList();
items2.Add("Second", "dfg");
items2.Add("First", "abc");

Надеюсь, это поможет!

1 голос
/ 13 февраля 2009

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

  • вставить
  • обновление
  • удалить
  • поиск
  • перечисление

Различные коллекции имеют разные характеристики производительности для каждой из этих операций. Например, массив быстро обновляет элемент, но занимает больше времени, чтобы вставить или удалить элемент. Поиск очень быстрый.

Сравните это со списком. Список очень быстро вставляется. Поиск занимает больше времени. Операции обновления и удаления требуют, чтобы у вас уже был элемент, и он выполняется довольно быстро. Перечисления для массива и списка примерно одинаковы.

Все коллекции также имеют определенное поведение, например, поддерживает ли коллекция сортировку. Если это так, то операции вставки / обновления / удаления займут больше времени, но ускорят поиск.

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

0 голосов
/ 13 февраля 2009

Есть много сообщений, связанных с этой проблемой, вы должны подумать, ЧТО вам действительно нужно сделать. Вам нужен строковый ключ (¿), как данные заполняются, нужен ли нативный метод, чтобы найти, существует ли какой-либо ключ, или существует какое-либо значение (?)

Дженерики являются наиболее используемыми мной, но есть причина для других;)

http://discuss.fogcreek.com/dotnetquestions/default.asp?cmd=show&ixPost=5119

0 голосов
/ 13 февраля 2009

Алгоритмы и структуры данных. У каждого есть свои преимущества и недостатки, и у каждого есть свое предназначение.

0 голосов
/ 13 февраля 2009

Два совета, которые я могу предложить: 1. Используйте общие коллекции как можно больше. 2. При выборе между универсальной коллекцией HashSet и List, действительно посмотрите, для чего вы собираетесь их использовать. Хеш-наборы могут быть быстрее при поиске, но они также замедляются при вставках (я обнаружил).

0 голосов
/ 13 февраля 2009

Коллекции, такие как Stacks, Queues, SortedList, Dictionary, HashTable - все это стандартные структуры данных, которые пригодятся в различных ситуациях.

Очередь включает реализацию FIFO без необходимости делать это самостоятельно. Стеки дают вам LIFO. SortedLists дает вам предварительно отсортированный список и т. Д.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...