Быстрые способы избежать дубликатов в списке <> в C #

Моя программа [C#](/tag5179) генерирует случайные
строки из заданного шаблона. Эти строки хранятся в списке.
Поскольку дубликатов не разрешено, я делаю это так:

```
List myList = new List();
for (int i = 0; i < total; i++) {
  string random_string = GetRandomString(pattern);
  if (!myList.Contains(random_string)) myList.Add(random_string);
}

```

Как вы можете себе представить, это работает отлично для
нескольких сотен записей. Но я столкнулся с ситуацией, чтобы
создать несколько миллионов строк. И с каждой добавленной строкой
проверка дубликатов становится медленнее и медленнее.

Есть ли более быстрые способы избежать дубликатов?

Используйте структуру данных, которая может намного более
эффективно определять, существует ли элемент, а именно
`HashSet` . Он может определить, находится ли элемент в
наборе в постоянное время, независимо от количества элементов в
наборе.

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



Don't use `List<>`. Use
`Dictionary<>` or `HashSet<>`
instead!



Самый простой способ - использовать это:

```
myList = myList.Distinct().ToList();

```

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

```
public IEnumerable GetRandomStrings(int total, string pattern)
{
    for (int i = 0; i < total; i++) 
    {
        yield return GetRandomString(pattern);
    }
}

...

myList = GetRandomStrings(total, pattern).Distinct().ToList();

```

Конечно, если вам не нужно обращаться к элементам по индексу,
вы, вероятно, могли бы повысить эффективность еще больше, сбросив
`ToList` и просто используя `IEnumerable`
.



You could use a `HashSet` if order is not
important:

```
HashSet myHashSet = new HashSet();
for (int i = 0; i < total; i++) 
{
   string random_string = GetRandomString(pattern);
   myHashSet.Add(random_string);
}

```

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

[MSDN](https://msdn.microsoft.com/en-us/library/bb359438.aspx)

Или если порядок важен, я бы рекомендовал использовать [SortedSet](https://msdn.microsoft.com/en-us/library/dd412070.aspx) (только для .net 4.5)



не очень хороший способ, но скорее быстрое исправление, возьмите
bool, чтобы проверить, есть ли в списке весь дубликат.

```
bool containsKey;
string newKey;

    public void addKey(string newKey){

         foreach(string key in MyKeys){
           if(key == newKey){
             containsKey = true;
          }
         }

      if(!containsKey){
       MyKeys.add(newKey);
     }else{
       containsKey = false;
     }

    }

```



Hashtable был бы более быстрым способом проверить, существует ли
элемент, чем список.



Ты пробовал:

```
myList = myList.Distinct()

```