Será que HashSet preservar a ordem de inserção?
Pergunta
Será que o href="https://msdn.microsoft.com/en-us/library/bb359438(v=vs.110).aspx" rel="noreferrer"> HashSet
coleção introduzido em .NET 3,5 preservar a ordem de inserção quando iterado usando foreach
?
O documentação estados, que a coleção não é ordenada, mas ele não diz nada sobre a ordem de inserção. Um pré-lançamento BCL entrada de blog estados que é desordenado, mas estados este artigo que ele é projetado para preservar a inserção ordem. Meu testes limitados sugere, que a ordem é preservada, mas que poderia ser uma coincidência.
Solução
Este HashSet MSDN página especificamente diz:
Um conjunto é uma coleção que não contém elementos duplicados, e cujos elementos estão em nenhuma ordem particular.
Outras dicas
Eu acho que o artigo alegando que preserva ordenação é apenas errado liso. Para testes simples a ordem de inserção pode muito bem ser preservada devido à estrutura interna, mas não é garantido e nem sempre funciona dessa forma. Vou tentar chegar a um contra-exemplo.
EDIT: Aqui está o contra-exemplo:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
var set = new HashSet<int>();
set.Add(1);
set.Add(2);
set.Add(3);
set.Remove(2);
set.Add(4);
foreach (int x in set)
{
Console.WriteLine(x);
}
}
}
Este gravuras 1, 4, 3 3, apesar de ter sido inserido antes de 4.
de possível que, se você nunca remover quaisquer itens, ele irá preservar a ordem de inserção. Eu não tenho certeza, mas eu não seria totalmente surpreso. No entanto, eu acho que seria uma idéia muito ruim que confiar em que:
- Não está documentada a trabalhar dessa maneira, e a documentação afirma explicitamente que não é classificada.
- Eu não olhei para as estruturas internas ou código fonte (que eu não tenho, obviamente) -. Eu teria que estudá-las cuidadosamente antes de fazer qualquer reclamação de uma forma firme
- A implementação poderia muito facilmente mudar entre as versões do quadro. Baseando-se isso seria como contando com a implementação
string.GetHashCode
não mudar - o que algumas pessoas fizeram voltar no .NET 1.1 dias, e então eles se queimou quando a implementação fez mudança no .NET 2.0 ...
Os estados de documentação:
Um HashSet <(Of <(T>)>) coleção não está classificada e não pode conter elementos duplicados. Se a ordem ou elemento de duplicação é mais importante do que o desempenho para o seu aplicativo, considere usar o List <(Of <(T>)>) classe juntamente com o método Sort.
Por isso, não importa se ele realmente preserva a ordem dos elementos na implementação atual, pois não está documentada como fazê-lo, e mesmo que parece agora isso pode mudar a qualquer momento no futuro (mesmo em um hotfix para o quadro).
Você deve estar programando contra contratos documentados , não detalhes da implementação .
Não é especificamente uma href="http://msdn.microsoft.com/en-us/library/dd412070.aspx" rel="nofollow"> coleção SortedSet<T> em .NET4 .
Isto lhe daria a classificação, mas pouco provável que seja a classificação do pedido de veiculação. Desde que você pode usar um IComparer
personalizado que você poderia, teoricamente, fazer este fazer nada.
Não, um conjunto de hash não vai preservar a ordem de inserção, pelo menos não de maneira previsível. Você poderia usar um LinkedHashSet (Java), ou um equivalente. A LinkedHashSet vai preservar a ordem.
Se você deseja ordem, você não deve mesmo estar usando um conjunto em primeiro lugar ... não é feita para elementos ordenados, exceto em casos excepcionais.
EDIT: Parece que eu estou pregando: -. / Desculpe
A leitura do código fonte para HashSet.AddIfNotPresent você pode ver ordem de inserção é preservada assumindo não houve quaisquer exclusões .
ordem conservas Assim new HashSet<string> { "Tom", "Dick", "Harry" }
, mas se você, em seguida, remover Dick e adicionar Rick, a ordem será [ "Tom", "Rick", "Harry"].