解決
このHashSet MSDNページには具体的に次のように記載されています。
セットは、重複する要素を含まないコレクションであり、要素の順序は特定ではありません。
他のヒント
順序を維持していると主張する記事は、まったく間違っていると思います。単純なテストの場合、内部構造のために挿入順序が保持される場合がありますが、保証されておらず、常にそのように機能するとは限りません。反例を考えてみます。
編集:これは反例です:
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);
}
}
}
4の前に3が挿入されたにもかかわらず、1、4、3を印刷します。
アイテムを削除しない場合、挿入順序が保持されることは可能です。よくわかりませんが、まったく驚かないでしょう。ただし、それに依存することは非常に悪い考えだと思います:
- そのように動作することは文書化されておらず、文書にはソートされていないことが明示的に記載されています。
- 私は内部構造やソースコードを見ていません(明らかに持っていません)-しっかりと主張する前にそれらを注意深く研究しなければなりません。
- 実装は、フレームワークのバージョン間で非常に簡単に変更できます。これに依存するのは、変更しない
string.GetHashCode
実装に依存するようなものです。これは、.NET 1.1時代に一部の人々が行ったもので、実装が.NET 2.0で did 変更したときに燃えました。 ..
ドキュメントの状態:
A HashSet <!> lt;(Of <!> lt;(T <!> gt;)<!> gt;)コレクションはソートされず、重複する要素を含めることはできません。アプリケーションのパフォーマンスよりも順序または要素の複製が重要な場合は、List <!> lt;(Of <!> lt;(T <!> gt;)<!> gt;)クラスとSortメソッドの併用を検討してください。 。
したがって、実際に現在の実装の要素の順序を保持するかどうかは関係ありません。なぜなら、そうするように文書化されていないためです。フレームワークの修正プログラム)。
実装の詳細ではなく、文書化された契約に対してプログラミングする必要があります。
.NET4には SortedSet<T>
コレクションがあります。
これにより並べ替えが可能になりますが、広告掲載順の並べ替えではありません。カスタムIComparer
を使用できるため、理論的にはこれを何でもできます。
いいえ、ハッシュセットは挿入順序を保持しません。少なくとも予測できません。 LinkedHashSet(Java)または同等のものを使用できます。 LinkedHashSetは順序を保持します。
順序が必要な場合、最初の場所でセットを使用するべきではありません ...例外的な場合を除いて、順序付けされた要素には使用されません。
編集:私は説教しているように聞こえます:-/ごめんなさい。
HashSet.AddIfNotPresent を見ると、挿入順序が保持されていることがわかります。削除が行われていないと仮定。
したがってnew HashSet<string> { "Tom", "Dick", "Harry" }
は順序を保持しますが、Dickを削除してRickを追加すると、順序は[<!> quot; Tom <!> quot ;, <!> quot; Rick <!> quot ;, < !> quot;ハリー<!> quot;]。