Estruturas de dados .NET:
Mais informações sobre por que ArrayList e List são realmente diferentes
Matrizes
Como um usuário declara, matrizes são a coleção "old school" (sim, matrizes são consideradas uma coleção, embora não façam parte dela System.Collections
). Mas, o que é "old school" sobre matrizes em comparação com outras coleções, ou seja, aquelas que você listou em seu título (aqui, ArrayList e List (Of T))? Vamos começar com o básico, olhando para matrizes.
Para começar, as matrizes no Microsoft .NET são "mecanismos que permitem tratar vários itens [relacionados à lógica] como uma única coleção" (consulte o artigo vinculado). O que isso significa? As matrizes armazenam membros individuais (elementos) sequencialmente, um após o outro na memória com um endereço inicial. Usando a matriz, podemos acessar facilmente os elementos armazenados em sequência, começando nesse endereço.
Além disso, e ao contrário de programar 101 concepções comuns, as matrizes realmente podem ser bastante complexas:
As matrizes podem ser de dimensão única, multidimensionais ou jadded (vale a pena ler sobre matrizes irregulares). As matrizes em si não são dinâmicas: uma vez inicializadas, uma matriz de n tamanho reserva espaço suficiente para armazenar n número de objetos. O número de elementos na matriz não pode aumentar ou diminuir. Dim _array As Int32() = New Int32(100)
reserva espaço suficiente no bloco de memória para que a matriz contenha 100 objetos do tipo primitivo Int32 (nesse caso, a matriz é inicializada para conter 0s). O endereço desse bloco é retornado para _array
.
De acordo com o artigo, o Common Language Specification (CLS) exige que todas as matrizes sejam baseadas em zero. Matrizes no .NET oferecem suporte a matrizes não baseadas em zero; no entanto, isso é menos comum. Como resultado do "comum" de matrizes baseadas em zero, a Microsoft passou muito tempo otimizando seu desempenho ; portanto, matrizes de dimensão única, baseadas em zero (SZs) são "especiais" - e realmente a melhor implementação de uma matriz (ao contrário de multidimensionais etc.) - porque as SZs têm instruções específicas de linguagem intermediária para manipulá-las.
As matrizes são sempre passadas por referência (como um endereço de memória) - uma peça importante do quebra-cabeça da matriz a ser conhecida. Enquanto eles fazem a verificação de limites (gerará um erro), a verificação de limites também pode ser desabilitada nas matrizes.
Novamente, o maior obstáculo às matrizes é que elas não são redimensionáveis. Eles têm uma capacidade "fixa". Apresentando ArrayList e List (Of T) à nossa história:
ArrayList - lista não genérica
O ArrayList (junto com List(Of T)
- embora haja algumas diferenças críticas, aqui explicadas mais adiante) - talvez seja melhor pensado como a próxima adição às coleções (no sentido amplo). ArrayList herda da interface IList (um descendente de 'ICollection'). As próprias ArrayLists são mais volumosas - exigindo mais sobrecarga - do que as Listas.
IList
permite que a implementação trate ArrayLists como listas de tamanho fixo (como Arrays); no entanto, além da funcionalidade adicional adicionada por ArrayLists, não há vantagens reais em usar ArrayLists de tamanho fixo, pois ArrayLists (sobre Arrays) nesse caso são marcadamente mais lentas.
Na minha leitura, ArrayLists não pode ser irregular: "O uso de matrizes multidimensionais como elementos ... não é suportado". Mais uma vez, outro prego no caixão de ArrayLists. ArrayLists também não são "digitado" - o que significa que, por baixo de tudo, um ArrayList é simplesmente uma matriz dinâmica de objetos: Object[]
. Isso requer muito boxe (implícito) e unboxing (explícito) ao implementar ArrayLists, aumentando novamente sua sobrecarga.
Pensamento sem fundamento: acho que lembro de ter lido ou ouvido falar de um de meus professores que ArrayLists são uma espécie de filho conceitual bastardo da tentativa de passar de Arrays para Coleções do tipo Lista, ou seja, embora tenha sido uma grande melhoria para Arrays, eles não são mais a melhor opção, pois um maior desenvolvimento foi feito com relação às coleções
Lista (de T): O que ArrayList se tornou (e esperava ser)
A diferença no uso da memória é significativa o suficiente para onde uma Lista (Of Int32) consumiu 56% menos memória que uma ArrayList contendo o mesmo tipo primitivo (8 MB vs. 19 MB na demonstração vinculada do cavalheiro acima: novamente, vinculada aqui ) - embora este é um resultado composto pela máquina de 64 bits. Essa diferença realmente demonstra duas coisas: primeiro (1), um "objeto" do tipo Int32 (ArrayList) é muito maior que um tipo primitivo do Int32 puro (List); segundo (2), a diferença é exponencial como resultado do funcionamento interno de uma máquina de 64 bits.
Então, qual é a diferença e o que é uma lista (de T) ? O MSDN define List(Of T)
como, "... uma lista fortemente digitada de objetos que podem ser acessados pelo índice". A importância aqui é o bit "fortemente tipado": uma Lista (de T) 'reconhece' tipos e armazena os objetos como seu tipo. Portanto, um Int32
é armazenado como Int32
e não como um Object
tipo. Isso elimina os problemas causados pelo boxe e unboxing.
O MSDN especifica que essa diferença só entra em jogo ao armazenar tipos primitivos e não tipos de referência. Além disso, a diferença realmente ocorre em grande escala: mais de 500 elementos. O mais interessante é que a documentação do MSDN diz: "É da sua vantagem usar a implementação específica do tipo da classe List (Of T) em vez de usar a classe ArrayList ...."
Essencialmente, List (Of T) é ArrayList, mas melhor. É o "equivalente genérico" de ArrayList. Como ArrayList, não é garantido que seja classificado até ser classificado (veja figura). A lista (Of T) também possui algumas funcionalidades adicionais.