Для поиска HashSet не сохраняет порядок вставки?



тут HashSet коллекция введена в .NET 3.5 сохранить порядок вставки при повторении с помощью foreach?



The документация заявляет, что коллекция не отсортирована, но она ничего не говорит о порядке вставки. Предварительный релиз BCL запись в блог утверждает, что он неупорядочен, но в этой статье заявляет, что он предназначен для сохранения порядка вставки. Мое ограниченное тестирование предполагает, что порядок сохраняется, но это может быть совпадением.

423   6  

6 ответов:

эта страница HashSet MSDN в частности, говорится:

набор-это коллекция, которая не содержит повторяющихся элементов, и элементы которой расположены в произвольном порядке.

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

EDIT: вот контрпример:

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);
        }
    }
}

это печатает 1, 4, 3, несмотря на то, что 3 был вставлен до 4.

Это возможно что если вы никогда не удаляете какие-либо элементы, это сохранит порядок вставки. Я не уверен, но я не был бы удивлен. Тем не менее, я думаю, что было бы очень плохой идеей полагаться на это:

  • это не документировано, так и в документации явно указано, что он не сортируется.
  • Я не смотрел на внутренние структуры или исходный код (которого у меня нет, очевидно) - мне нужно было бы тщательно изучить их, прежде чем делать какие-либо такие заявления в твердой манере.
  • в реализация может очень легко меняться между версиями платформы. Полагаться на это было бы как полагаться на string.GetHashCode реализация не меняется - что некоторые люди делали еще в .NET 1.1 дней, а затем они сгорели, когда реализация сделал изменение в .NET 2.0...

в документации:

коллекция HashSet)>) не сортируется и не может содержать повторяющиеся элементы. Если порядок или дублирование элементов является более важным, чем производительность для вашего приложения, рассмотрите возможность использования класса List)>) вместе с методом сортировки.

поэтому не имеет значения, действительно ли он сохраняет порядок элементов в текущей реализации, потому что он не документирован как это делается, и даже если это кажется сейчас, это может измениться в любой момент в будущем (даже в исправлении к структуре).

вы должны программировать в отношении документально контрактов, а не детали реализации.

нет, набор хэшей не будет сохранять порядок вставки, по крайней мере, не предсказуемо. Вы можете использовать LinkedHashSet (Java) или его эквивалент. В LinkedHashSet будет сохранить порядок.

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

EDIT: похоже, я проповедую : - / извините.

есть конкретно a SortedSet<T> коллекция in. NET4.

это даст вам сортировку, но вряд ли будет сортировка порядка вставки. Так как вы можете использовать пользовательский IComparer теоретически вы могли бы сделать это сделать что угодно.

чтение исходного кода для HashSet.AddIfNotPresent вы можете видеть, что порядок вставки сохраняется предполагая, что не было никаких удалений.

new HashSet<string> { "Tom", "Dick", "Harry" } сохраняет порядок, но если затем удалить Дик и добавить Рик, порядок будет ["Том", "Рик", "Гарри"].

Comments

    Ничего не найдено.