Разница между Lookup () и словарём (Of list ())

107

Я пытаюсь обернуть голову, какие структуры данных наиболее эффективны и когда/где их использовать.

Теперь, может быть, я просто недостаточно разбираюсь в структурах, но как отличается ILookup(of key, ...) от Dictionary(of key, list(of ...))?

Также, где бы я хотел использовать ILookup и где он был бы более эффективным с точки зрения скорости программы/памяти/доступа к данным и т.д.?

Теги:
linq

5 ответов

177
Лучший ответ

Две существенные отличия:

  • Lookup является неизменным. Yay:) (По крайней мере, я считаю, что конкретный класс Lookup неизменен, а интерфейс ILookup не содержит каких-либо мутирующих элементов. Конечно, могут быть и другие изменчивые реализации).
  • Когда вы просматриваете ключ, отсутствующий в поиске, вы получаете пустую последовательность назад вместо KeyNotFoundException. (Следовательно, нет TryGetValue, AFAICR.)

Они, вероятно, будут эквивалентны по эффективности - поиск может, например, использовать Dictionary<TKey, GroupingImplementation<TValue>> за кулисами. Выбирайте между ними, исходя из ваших требований. Лично я считаю, что поиск обычно лучше, чем Dictionary<TKey, List<TValue>>, в основном из-за первых двух точек выше.

Обратите внимание, что в качестве детали реализации конкретная реализация IGrouping<,>, которая используется для значений реализует IList<TValue>, что означает, что она эффективна для использования с Count(), ElementAt() и т.д.

  • 0
    Если поиск несуществующего ключа приводит к пустой последовательности, а не к исключению, то он очень не может быть использован в качестве общей коллекции imo. Это нормально в случае неизменной коллекции, которая является побочным продуктом запросов linq.
  • 0
    @nawfal - это именно то, для чего нужны поиски. Из msdn : «Вы можете создать экземпляр Lookup <TKey, TElement>, вызвав ToLookup для объекта, который реализует IEnumerable <T>.»
20

Оба a Dictionary<Key, List<Value>> и a Lookup<Key, Value> логически могут хранить данные, упорядоченные аналогичным образом, и оба имеют один и тот же порядок эффективности. Основное отличие: Lookup является неизменным: он не имеет методов Add() и не имеет открытого конструктора (и, как сказал Джон, вы можете запросить несуществующий ключ без исключения и иметь ключ как часть группировки).

Что вы используете, это действительно зависит от того, как вы хотите их использовать. Если вы поддерживаете карту ключа для нескольких значений, которые постоянно изменяются, то Dictionary<Key, List<Value>>, вероятно, лучше, поскольку он изменен.

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

19

Интересно, что никто не заявил о самой большой разнице (взято непосредственно из MSDN):

Поиск похож на словарь. разница заключается в том, что словарь сопоставляет ключи с одиночными значения, тогда как Lookup сопоставляет ключи с коллекциями значения.

  • 32
    Проверьте вопрос: речь идет о разнице между Lookup <TKey, TValue> и словарем <TKey, List <TValue >>, так что эта разница уже видна явно.
9

Основное различие между ILookup<K,V> и a Dictionary<K, List<V>> заключается в том, что словарь изменчив; вы можете добавлять или удалять ключи, а также добавлять или удалять элементы из списка, который просматривается. ILookup является неизменным и не может быть изменен после создания.

Основная реализация обоих механизмов будет либо одинаковой, либо подобной, поэтому их скорость поиска и объем памяти будут примерно одинаковыми.

  • 1
    @JohnBustos С точки зрения производительности, нет. Это чисто логично. Вы можете передавать ссылки на структуру вокруг, чтобы не беспокоиться о том, что кто-то еще изменит ее из-под вас. Вы можете сделать предположение о том, что неизменным является то, чего нельзя было бы сделать, если бы оно было изменчивым.
  • 0
    Спасибо, Servy, это очень хороший момент, когда вы часто передаете столько переменных ByRef - по крайней мере, эту, которую вы точно не можете изменить. Спасибо!
Показать ещё 4 комментария
5

Еще одно отличие, которое не упомянуто, заключается в том, что Lookup() поддерживает нулевые ключи:

Класс поиска реализует интерфейс ILookup. Поиск очень похож на словарь, за исключением того, что нескольким значениям разрешено сопоставлять один и тот же ключ, а нулевые ключи поддерживаются.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню