Recolhas e Estruturas de Dados
Dados semelhantes podem muitas vezes ser tratados de forma mais eficiente quando armazenados e manipulados como uma recolha. Pode utilizar a System.Array classe ou as classes nos System.Collectionsespaços System.Collections.Genericde nomes System.Collections.ConcurrentSystem.Collections.Immutable para adicionar, remover e modificar elementos individuais ou uma gama de elementos numa coleção.
Existem dois tipos principais de coleções; coleções genéricas e coleções não genéricas. As coleções genéricas são tipo de segurança na hora da compilação. Por isso, as coleções genéricas normalmente oferecem um melhor desempenho. As coleções genéricas aceitam um parâmetro de tipo quando são construídas e não requerem que você lance de e para o Object tipo quando adiciona ou remove itens da coleção. Além disso, a maioria das coleções genéricas são suportadas em aplicações Windows Store. As coleções não genéricas armazenam itens como Object, requerem casting, e a maioria não é suportada para o desenvolvimento de aplicações Windows Store. No entanto, pode ver coleções não genéricas em código mais antigo.
Começando com .NET Framework 4, as coleções no espaço de System.Collections.Concurrent nome fornecem operações eficientes de segurança para fios para aceder a itens de recolha a partir de vários fios. As classes de recolha imutáveis no espaço de System.Collections.Immutable nomes (pacote NuGet) são inerentemente seguras porque as operações são realizadas numa cópia da coleção original e a coleção original não pode ser modificada.
Características comuns da coleção
Todas as coleções fornecem métodos para adicionar, remover ou encontrar itens na coleção. Além disso, todas as coleções que implementam direta ou indiretamente a ICollection interface ou a ICollection<T> interface partilham estas funcionalidades:
A capacidade de enumerar a coleção
.AS coleções .NET implementam System.Collections.IEnumerable ou System.Collections.Generic.IEnumerable<T> permitem a iterada através da recolha. Um enumerador pode ser considerado como um ponteiro móvel para qualquer elemento da coleção. O foreach, em declaração e o For Each... A Próxima Declaração utiliza o enumerador exposto pelo GetEnumerator método e esconde a complexidade da manipulação do enumerador. Além disso, qualquer coleção que implemente System.Collections.Generic.IEnumerable<T> é considerada um tipo de consulta e pode ser consultada com LINQ. As consultas linq fornecem um padrão comum para aceder a dados. São tipicamente mais concisos e legíveis do que os loops padrão
foreach
, e fornecem capacidades de filtragem, encomenda e agrupamento. As consultas linq também podem melhorar o desempenho. Para obter mais informações, consulte LINQ to Objects (C#), LINQ to Objects (Visual Basic), LinQ Paralelo (PLINQ), Introdução às Consultas LINQ (C#)) e Operações de Consulta Básica (Visual Basic).A capacidade de copiar o conteúdo da coleção para uma matriz
Todas as coleções podem ser copiadas para uma matriz utilizando o método CopyTo ; no entanto, a ordem dos elementos da nova matriz baseia-se na sequência em que o enumerador os devolve. A matriz resultante é sempre unidimensional com um limite inferior de zero.
Além disso, muitas classes de recolha contêm as seguintes características:
Capacidade e Propriedades de Contagem
A capacidade de uma coleção é o número de elementos que pode conter. A contagem de uma coleção é o número de elementos que realmente contém. Algumas coleções escondem a capacidade ou a contagem ou ambos.
A maioria das coleções expande-se automaticamente na capacidade quando a capacidade atual é alcançada. A memória é realojada, e os elementos são copiados da coleção antiga para a nova. Isto reduz o código necessário para a utilização da coleção; no entanto, o desempenho da coleção pode ser negativamente afetado. Por exemplo, para List<T>, se Count for menos do que Capacity, adicionar um item é uma operação O(1). Se a capacidade tiver de ser aumentada para acomodar o novo elemento, adicionar um item torna-se uma operação O
n
,,onden
está Count. A melhor maneira de evitar um mau desempenho causado por múltiplas reafectações é definir a capacidade inicial para ser o tamanho estimado da coleção.A BitArray é um caso especial; a sua capacidade é a mesma do seu comprimento, que é o mesmo que a sua contagem.
Um limite inferior consistente
O limite inferior de uma coleção é o índice do seu primeiro elemento. Todas as coleções indexadas nos System.Collections espaços de nome têm um limite inferior de zero, o que significa que são indexadas a 0. Array tem um limite inferior de zero por defeito, mas um limite inferior diferente pode ser definido ao criar um exemplo da classe Array usando Array.CreateInstance.
Sincronização para acesso a partir de vários fios (System.Collections apenas classes).
Os tipos de recolha não genéricos no espaço de System.Collections nome proporcionam alguma segurança do fio com sincronização; normalmente expostos através dos SyncRoot e IsSynchronized membros. Estas coleções não são seguras por defeito. Se necessitar de acesso multi-roscado escalável e eficiente a uma coleção, use uma das classes no espaço de System.Collections.Concurrent nomes ou considere usar uma coleção imutável. Para mais informações, consulte a Thread-Cofre Collections.
Escolha uma coleção
Em geral, deve usar coleções genéricas. A tabela seguinte descreve alguns cenários de recolha comuns e as classes de recolha que pode usar para esses cenários. Se você é novo em coleções genéricas, esta tabela irá ajudá-lo a escolher a coleção genérica que funciona melhor para a sua tarefa.
Eu quero... | Opções genéricas de recolha | Opções de recolha não genéricas | Opções de recolha seguras ou imutáveis |
---|---|---|---|
Armazenar itens como pares chave/valor para uma procura rápida por chave | Dictionary<TKey,TValue> | Hashtable (Uma coleção de pares chave/valor que são organizados com base no código de haxixe da chave.) |
ConcurrentDictionary<TKey,TValue> ReadOnlyDictionary<TKey,TValue> ImmutableDictionary<TKey,TValue> |
Aceder a itens por índice | List<T> | Array ArrayList |
ImmutableList<T> ImmutableArray |
Utilize os itens primeiro no primeiro lugar (FIFO) | Queue<T> | Queue | ConcurrentQueue<T> ImmutableQueue<T> |
Utilizar dados Last-In-First-Out (LIFO) | Stack<T> | Stack | ConcurrentStack<T> ImmutableStack<T> |
Aceder a itens sequencialmente | LinkedList<T> | Sem recomendação | Sem recomendação |
Receba notificações quando os itens forem removidos ou adicionados à coleção. (instrumentos INotifyPropertyChanged e INotifyCollectionChanged) | ObservableCollection<T> | Sem recomendação | Sem recomendação |
Uma coleção ordenada | SortedList<TKey,TValue> | SortedList | ImmutableSortedDictionary<TKey,TValue> ImmutableSortedSet<T> |
Um conjunto para funções matemáticas | HashSet<T> SortedSet<T> |
Sem recomendação | ImmutableHashSet<T> ImmutableSortedSet<T> |
Complexidade algorítmica das coleções
Ao escolher uma classe de coleção, vale a pena considerar potenciais tradeoffs no desempenho. Utilize a tabela seguinte para fazer referência à forma como vários tipos de recolha mutáveis se comparam em complexidade algorítmica às suas correspondentes congéneres imutáveis. Muitas vezes, os tipos de recolha imutáveis são menos performantes, mas proporcionam imutabilidade - o que muitas vezes é um benefício comparativo válido.
Mutável | Amortizado | Pior caso | Imutável | Complexidade |
---|---|---|---|---|
Stack<T>.Push |
O(1) | O(n ) |
ImmutableStack<T>.Push |
O(1) |
Queue<T>.Enqueue |
O(1) | O(n ) |
ImmutableQueue<T>.Enqueue |
O(1) |
List<T>.Add |
O(1) | O(n ) |
ImmutableList<T>.Add |
O(log n ) |
List<T>.Item[Int32] |
O(1) | O(1) | ImmutableList<T>.Item[Int32] |
O(log n ) |
List<T>.Enumerator |
O(n ) |
O(n ) |
ImmutableList<T>.Enumerator |
O(n ) |
HashSet<T>.Add , procura |
O(1) | O(n ) |
ImmutableHashSet<T>.Add |
O(log n ) |
SortedSet<T>.Add |
O(log n ) |
O(n ) |
ImmutableSortedSet<T>.Add |
O(log n ) |
Dictionary<T>.Add |
O(1) | O(n ) |
ImmutableDictionary<T>.Add |
O(log n ) |
Dictionary<T> lookup |
O(1) | O(1) – ou estritamente O(n ) |
ImmutableDictionary<T> lookup |
O(log n ) |
SortedDictionary<T>.Add |
O(log n ) |
O(n log n ) |
ImmutableSortedDictionary<T>.Add |
O(log n ) |
A List<T>
pode ser enumerada de forma eficiente usando um for
loop ou um foreach
loop. Um ImmutableList<T>
, no entanto, faz um mau trabalho dentro de um for
loop, devido ao tempo O (log n
) para o seu indexante. Enumerar um ImmutableList<T>
foreach
loop é eficiente porque ImmutableList<T>
usa uma árvore binária para armazenar os seus dados em vez de uma matriz simples como List<T>
utilizações. Uma matriz pode ser muito rapidamente indexada, enquanto uma árvore binária deve ser descendo até que o nó com o índice desejado seja encontrado.
Além disso, SortedSet<T>
tem a mesma complexidade que ImmutableSortedSet<T>
. Isso é porque ambos usam árvores binárias. A diferença significativa, é claro, é que ImmutableSortedSet<T>
usa uma árvore binária imutável. Uma vez ImmutableSortedSet<T>
que também oferece uma System.Collections.Immutable.ImmutableSortedSet<T>.Builder classe que permite mutação, você pode ter imutabilidade e desempenho.
Tópicos relacionados
Título | Descrição |
---|---|
Selecionando uma classe de coleção | Descreve as diferentes coleções e ajuda-o a selecionar uma para o seu cenário. |
Tipos de recolha comumente usados | Descreve tipos de recolha genéricos e não-genes comumente usados, tais como System.Array, System.Collections.Generic.List<T>e System.Collections.Generic.Dictionary<TKey,TValue>. |
Quando usar coleções genéricas | Discute-se a utilização de tipos de recolha genérica. |
Comparações e Sorts Dentro de Coleções | Discute-se a utilização de comparações de igualdade e comparações de triagem em coleções. |
Tipos de recolha ordenado | Descreve desempenho e características de coleções ordenadas |
Tipos de coleção de hashtable e dicionário | Descreve as características de tipos de dicionários genéricos e não genéricos baseados em haxixe. |
Coleções thread-Cofre | Descreve tipos de recolha como System.Collections.Concurrent.BlockingCollection<T> e System.Collections.Concurrent.ConcurrentBag<T> que suportam acesso simultâneo seguro e eficiente a partir de vários fios. |
System.Collections.Imuttable | Introduz as coleções imutáveis e fornece ligações aos tipos de recolha. |
Referência
System.Array System.Collections System.Collections.Concurrent System.Collections.Generic System.Collections.Specialized System.Linq System.Collections.Immutable