Então eu encontrei um Dictionary<int, int>
hoje no trabalho. Isso me pareceu estranho, porque eu provavelmente usaria um List<int>
. Existe uma diferença e haveria um caso de uso em que uma estrutura seria preferida à outra?
c#
.net
data-structures
ZeroDivide
fonte
fonte
List<T>
dentro da estrutura .NET é uma matriz de acesso aleatório, em que uma operação de pesquisa geralmente é mais rápida que aDictionary<int,T>
.Dictionary<TKey, TValue>
.Respostas:
Você usaria a
Dictionary<int, int>
se seus índices tiverem um significado especial além de apenas o posicionamento posicional.O exemplo imediato que vem à mente é armazenar uma coluna de identificação e uma coluna int em um banco de dados. Por exemplo, se você tiver uma
[person-id]
coluna e uma[personal-pin]
coluna, poderá trazê-las para aDictionary<int, int>
. Dessa forma,pinDict[person-id]
você recebe um PIN, mas o índice é significativo e não apenas uma posição em aList<int>
.Mas, realmente, sempre que você tiver duas listas relacionadas de números inteiros, essa pode ser uma estrutura de dados apropriada.
fonte
List<int>
, e não um dicionário. Veja minha resposta abaixo.Pense em
List
como uma matriz eDictionary
como uma tabela de hash . Você usaria apenas oDictionary
se precisasse mapear (ou associar) chaves significativas para valores, enquanto umList
único mapeia (ou associa) posições (ou índices) para valores.Por exemplo, digamos que você queira armazenar uma associação entre a idade de uma pessoa e sua altura. Você pode usar a
Dictionary<int, int>
para mapear a idade da pessoa (aint
) para sua altura (aint
):Não é um exemplo muito útil, mas o ponto é que você não seria capaz de fazer isso de maneira tão elegante com um
List
porque seria necessário armazenar esses valores posicionalmente.fonte
List
lida com pedido , ondeDictionary
lida com associação . Se você precisar obter seus dados sempre em uma determinada ordem, ou se a ordem deles em relação um ao outro é importante, aList
é o caminho a percorrer.Dictionaries
tendem a ser desordenados e lidam com relacionamentos de chave -> valor de mapeamento.Semanticamente, a
Dictionary<int, T>
eList<T>
são muito semelhantes, ambos são contêineres de acesso aleatório da estrutura .NET. Para usar uma lista como substituta de um dicionário, você precisa de um valor especial no seu tipoT
(comonull
) para representar os espaços vazios na sua lista. SeT
não for do tipo anulávelint
, você pode usarint?
ou, se espera apenas armazenar valores positivos, também pode usar um valor especial como -1 para representar espaços vazios.Qual você escolherá depende do intervalo dos valores-chave. Se suas chaves
Dictionary<int, T>
estão dentro de um intervalo inteiro, sem muitas lacunas entre elas (por exemplo, 80 valores entre [0, ... 100]), aList<T>
será mais apropriado, pois o acesso pelo índice é mais rápido e há menos sobrecarga de memória e tempo em comparação com um dicionário nesse caso.Se seus valores-chave forem 100
int
valores de um intervalo como [0, ..., 1000000], seráList<T>
necessário ter memória para armazenar 1000000 valores de T, onde seu dicionário precisará apenas de memória em uma ordem de magnitude em torno de 100 valores de T, 100 valores de int (mais alguma sobrecarga, na realidade, esperam cerca de 2 vezes a memória para armazenar essas 100 chaves e valores). Portanto, no último caso, um dicionário será mais apropriado.fonte
List<KeyValuePair<int,T>>
, não há operação de pesquisa O (1) disponível. Segundo, os elementos emList<KeyValuePair<int,T>>
podem ter uma ordem específica, independente de seus valores-chave. Se você precisar do último, mas não do primeiro,List<KeyValuePair<int,T>>
ouList<Tuple<int,T>>
pode ser a melhor escolha. Se você precisar de ambos, também háOrderedDictionary
.Como alguém pode considerá-los equivalentes?
O dicionário é escasso e permite inserções aleatórias, mas torna o percurso em ordem um problema, a Lista não é esparsa e a inserção fora de ordem é cara, pois fornece inerentemente o percurso em ordem.
Haveria muito poucas situações em que uma não fosse dramaticamente superior à outra.
fonte
Além: Outras linguagens de programação se referem a esse tipo de estrutura de dados como um Mapa, em vez de um Dicionário.
Se seus dados puderem ser definidos significativamente como pares de chave / valor, um Dicionário fornecerá um acesso muito mais rápido se você precisar encontrar um valor usando sua chave.
Por exemplo, suponha que você tenha uma lista de clientes. Cada cliente inclui detalhes como nome e endereço e um número de cliente exclusivo. Suponha que você também tenha uma lista de pedidos em processamento. Cada pedido conterá detalhes do que está sendo feito e precisará incluir o número do cliente da pessoa que o solicitou.
Quando um pedido está pronto para ser enviado, você precisa encontrar o endereço para o qual ele é enviado. Se os clientes estiverem armazenados como uma lista simples, será necessário pesquisar na lista inteira para encontrar o cliente com o número certo de clientes. Em vez disso, você pode armazenar os clientes em um dicionário, com o número do cliente como a chave. O dicionário agora permite que você obtenha o cliente correto em uma etapa sem nenhuma pesquisa.
fonte
O dicionário usa hash para procurar os dados. Um dicionário calculou primeiro um valor de hash para a chave e esse valor de hash leva ao intervalo de dados de destino. Depois disso, cada elemento no bucket precisa ser verificado quanto à igualdade. Mas, na verdade, a lista será mais rápida que o dicionário na primeira pesquisa de itens, porque não há nada para pesquisar na primeira etapa. Mas, na segunda etapa, a lista precisa examinar o primeiro item e depois o segundo item. Portanto, cada etapa da pesquisa leva mais e mais tempo. Quanto maior a lista, mais tempo leva.
Mais sobre .... Dicionário Vs List com exemplo.
fonte
Se o código em questão estiver armazenando dois conjuntos de valores correlacionados, a classe Dictionary fornecerá uma maneira indexada de procurar valores por uma chave. Se houver apenas um conjunto de valores, mas esse conjunto precisar ser acessado aleatoriamente (talvez para verificar a existência de uma chave em um conjunto) e os valores forem exclusivos, um HashSet pode ser a melhor classe de conjunto a ser usada.
fonte
Essas são ótimas respostas que parecem cobrir as bases.
Outra consideração que vou oferecer é que os dicionários (em C #) são mais complexos do ponto de vista da codificação. A existência de listas e dicionários na mesma base de código dificulta a manutenção do código, pois ambos os métodos apresentam diferenças sutis em como executar operações básicas, como pesquisar e organizar dados de objetos. Minha perspectiva é que, a menos que você precise de um dicionário por algum motivo justificável, use uma lista.
fonte